Commit 168fef361ea for php.net

commit 168fef361ea16fdf97391674087db516c25450c3
Author: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com>
Date:   Fri Apr 10 11:42:17 2026 +0200

    Throw ValueError when a wrong flag value is provided to the second argument of `scandir()` (#19373)

diff --git a/NEWS b/NEWS
index 6a37ca9791c..f39dd0954a5 100644
--- a/NEWS
+++ b/NEWS
@@ -152,6 +152,8 @@ PHP                                                                        NEWS
   . Add enum SortDirection. (timwolla)
   . pathinfo() raises a ValueError with an invalid $flags argument.
     (David Carlier)
+  . Passing an invalid flag value to the second argument of scandir() will now
+    throw a ValueError. (alexandre-daubois)

 - Streams:
   . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream
diff --git a/UPGRADING b/UPGRADING
index a7c91c4501e..33717ac1ed5 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -139,6 +139,8 @@ PHP 8.6 UPGRADE NOTES
 - Standard:
   . pathinfo() now raises a ValueError when an invalid $flag argument
     value is passed.
+  . scandir() now raises a ValueError when an invalid $sorting_order
+    argument value is passed.

 - Zip:
   . ZipArchive::extractTo now raises a TypeError for the
diff --git a/ext/standard/dir.c b/ext/standard/dir.c
index 730ef615490..a7e080ce2ab 100644
--- a/ext/standard/dir.c
+++ b/ext/standard/dir.c
@@ -588,9 +588,13 @@ PHP_FUNCTION(scandir)
 		n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort);
 	} else if (flags == PHP_SCANDIR_SORT_NONE) {
 		n = php_stream_scandir(dirn, &namelist, context, NULL);
-	} else {
+	} else if (flags == PHP_SCANDIR_SORT_DESCENDING) {
 		n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr);
-	}
+	} else {
+		zend_argument_value_error(2, "must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants");
+		RETURN_THROWS();
+    }
+
 	if (n < 0) {
 		php_error_docref(NULL, E_WARNING, "(errno %d): %s", errno, strerror(errno));
 		RETURN_FALSE;
diff --git a/ext/standard/tests/dir/scandir_invalid_flag.phpt b/ext/standard/tests/dir/scandir_invalid_flag.phpt
new file mode 100644
index 00000000000..76838dc869b
--- /dev/null
+++ b/ext/standard/tests/dir/scandir_invalid_flag.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Provide wrong flags to scandir()
+--FILE--
+<?php
+try {
+    scandir('something', -1);
+} catch (ValueError $e) {
+    echo $e->getMessage() . "\n";
+}
+?>
+--EXPECT--
+scandir(): Argument #2 ($sorting_order) must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants
diff --git a/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt b/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt
deleted file mode 100644
index 44d8b6daa5f..00000000000
--- a/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt
+++ /dev/null
@@ -1,71 +0,0 @@
---TEST--
-Test scandir() function : usage variations - different ints as $sorting_order arg
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
-  die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/*
- * Pass different integers as $sorting_order argument to test how scandir()
- * re-orders the array
- */
-
-echo "*** Testing scandir() : usage variations ***\n";
-
-// include for create_files/delete_files functions
-include(__DIR__ . '/../file/file.inc');
-
-// create directory and files
-$dir = __DIR__ . '/私はガラスを食べられますscandir_variation9';
-mkdir($dir);
-@create_files($dir, 2, "numeric", 0755, 1, "w", "私はガラスを食べられますfile");
-
-// different ints to pass as $sorting_order argument
-$ints = array (PHP_INT_MAX, -PHP_INT_MAX, 0);
-
-foreach($ints as $sorting_order) {
-    var_dump( scandir($dir, $sorting_order) );
-}
-
-delete_files($dir, 2, "私はガラスを食べられますfile");
-?>
---CLEAN--
-<?php
-$dir = __DIR__ . '/私はガラスを食べられますscandir_variation9';
-rmdir($dir);
-?>
---EXPECT--
-*** Testing scandir() : usage variations ***
-array(4) {
-  [0]=>
-  string(45) "私はガラスを食べられますfile2.tmp"
-  [1]=>
-  string(45) "私はガラスを食べられますfile1.tmp"
-  [2]=>
-  string(2) ".."
-  [3]=>
-  string(1) "."
-}
-array(4) {
-  [0]=>
-  string(45) "私はガラスを食べられますfile2.tmp"
-  [1]=>
-  string(45) "私はガラスを食べられますfile1.tmp"
-  [2]=>
-  string(2) ".."
-  [3]=>
-  string(1) "."
-}
-array(4) {
-  [0]=>
-  string(1) "."
-  [1]=>
-  string(2) ".."
-  [2]=>
-  string(45) "私はガラスを食べられますfile1.tmp"
-  [3]=>
-  string(45) "私はガラスを食べられますfile2.tmp"
-}
diff --git a/ext/standard/tests/dir/scandir_variation9.phpt b/ext/standard/tests/dir/scandir_variation9.phpt
deleted file mode 100644
index 56e5575e559..00000000000
--- a/ext/standard/tests/dir/scandir_variation9.phpt
+++ /dev/null
@@ -1,65 +0,0 @@
---TEST--
-Test scandir() function : usage variations - different ints as $sorting_order arg
---FILE--
-<?php
-/*
- * Pass different integers as $sorting_order argument to test how scandir()
- * re-orders the array
- */
-
-echo "*** Testing scandir() : usage variations ***\n";
-
-// include for create_files/delete_files functions
-include(__DIR__ . '/../file/file.inc');
-
-// create directory and files
-$dir = __DIR__ . '/scandir_variation9';
-mkdir($dir);
-@create_files($dir, 2);
-
-// different ints to pass as $sorting_order argument
-$ints = array (PHP_INT_MAX, -PHP_INT_MAX, 0);
-
-foreach($ints as $sorting_order) {
-    var_dump( scandir($dir, $sorting_order) );
-}
-
-delete_files($dir, 2);
-?>
---CLEAN--
-<?php
-$dir = __DIR__ . '/scandir_variation9';
-rmdir($dir);
-?>
---EXPECT--
-*** Testing scandir() : usage variations ***
-array(4) {
-  [0]=>
-  string(9) "file2.tmp"
-  [1]=>
-  string(9) "file1.tmp"
-  [2]=>
-  string(2) ".."
-  [3]=>
-  string(1) "."
-}
-array(4) {
-  [0]=>
-  string(9) "file2.tmp"
-  [1]=>
-  string(9) "file1.tmp"
-  [2]=>
-  string(2) ".."
-  [3]=>
-  string(1) "."
-}
-array(4) {
-  [0]=>
-  string(1) "."
-  [1]=>
-  string(2) ".."
-  [2]=>
-  string(9) "file1.tmp"
-  [3]=>
-  string(9) "file2.tmp"
-}