diff --git a/NEWS b/NEWS index 6a37ca9791c5..f39dd0954a50 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 a7c91c4501e9..33717ac1ed57 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/array.c b/ext/standard/array.c index 037f13a7a464..7db5dcb72944 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4799,7 +4799,7 @@ PHP_FUNCTION(array_change_key_case) zend_string *string_key; zend_string *new_key; zend_ulong num_key; - zend_long change_to_upper=0; + zend_long change_to_upper = PHP_CASE_LOWER; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_ARRAY(array) @@ -4807,13 +4807,18 @@ PHP_FUNCTION(array_change_key_case) Z_PARAM_LONG(change_to_upper) ZEND_PARSE_PARAMETERS_END(); + if (change_to_upper != PHP_CASE_LOWER && change_to_upper != PHP_CASE_UPPER) { + zend_argument_value_error(2, "must be either CASE_LOWER or CASE_UPPER"); + RETURN_THROWS(); + } + array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) { if (!string_key) { entry = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); } else { - if (change_to_upper) { + if (change_to_upper == PHP_CASE_UPPER) { new_key = zend_string_toupper(string_key); } else { new_key = zend_string_tolower(string_key); diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 730ef6154907..a7e080ce2abe 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/array/array_change_key_case_flag_error.phpt b/ext/standard/tests/array/array_change_key_case_flag_error.phpt new file mode 100644 index 000000000000..e83a21815c99 --- /dev/null +++ b/ext/standard/tests/array/array_change_key_case_flag_error.phpt @@ -0,0 +1,14 @@ +--TEST-- +array_change_key_case(): invalid $case argument +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: array_change_key_case(): Argument #2 ($case) must be either CASE_LOWER or CASE_UPPER diff --git a/ext/standard/tests/array/array_change_key_case_variation.phpt b/ext/standard/tests/array/array_change_key_case_variation.phpt deleted file mode 100644 index c221a3f34101..000000000000 --- a/ext/standard/tests/array/array_change_key_case_variation.phpt +++ /dev/null @@ -1,50 +0,0 @@ ---TEST-- -Test array_change_key_case() function - 2 ---FILE-- - 1, "two" => 2, "THREE" => 3, "FOUR" => "four"); - -/* use 'case' argument other than CASE_LOWER & CASE_UPPER */ -try { - var_dump(array_change_key_case($item, "CASE_UPPER")); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -var_dump(array_change_key_case($item, 5)); - -/* when keys are different in terms of only case */ -/* should return one value key pair with key being in lowercase */ -var_dump( array_change_key_case( array("ONE" => 1, "one" => 3, "One" => 4) ) ); - -/* should return one value key pair with key being in uppercase */ -var_dump( array_change_key_case( array("ONE" => 1, "one" => 2, "One" => 3), CASE_UPPER ) ); -var_dump( array_change_key_case( array("ONE" => 1, "one" => 1, "One" => 2), 5 ) ); - -echo "end\n"; -?> ---EXPECT-- -array_change_key_case(): Argument #2 ($case) must be of type int, string given -array(4) { - ["ONE"]=> - int(1) - ["TWO"]=> - int(2) - ["THREE"]=> - int(3) - ["FOUR"]=> - string(4) "four" -} -array(1) { - ["one"]=> - int(4) -} -array(1) { - ["ONE"]=> - int(3) -} -array(1) { - ["ONE"]=> - int(2) -} -end diff --git a/ext/standard/tests/array/array_change_key_case_variation4.phpt b/ext/standard/tests/array/array_change_key_case_variation4.phpt deleted file mode 100644 index 82d211451638..000000000000 --- a/ext/standard/tests/array/array_change_key_case_variation4.phpt +++ /dev/null @@ -1,132 +0,0 @@ ---TEST-- -Test array_change_key_case() function : usage variations - different int values for $case ---FILE-- - 'un', 'TWO' => 'deux', 'three' => 'trois'); -for ($i = -5; $i <=5; $i += 1){ - echo "\n-- \$sort argument is $i --\n"; - $temp = $input; - var_dump(array_change_key_case($temp, $i)); -} - -echo "Done"; -?> ---EXPECT-- -*** Testing array_change_key_case() : usage variations *** - --- $sort argument is -5 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -4 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -3 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -2 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -1 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 0 -- -array(3) { - ["one"]=> - string(2) "un" - ["two"]=> - string(4) "deux" - ["three"]=> - string(5) "trois" -} - --- $sort argument is 1 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 2 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 3 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 4 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 5 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} -Done 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 000000000000..76838dc869b8 --- /dev/null +++ b/ext/standard/tests/dir/scandir_invalid_flag.phpt @@ -0,0 +1,12 @@ +--TEST-- +Provide wrong flags to scandir() +--FILE-- +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 44d8b6daa5f9..000000000000 --- 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-- - ---FILE-- - ---CLEAN-- - ---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 56e5575e5590..000000000000 --- 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-- - ---CLEAN-- - ---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" -} diff --git a/ext/standard/tests/math/pi_basic.phpt b/ext/standard/tests/math/pi_basic.phpt index 10814ae8e819..acb95ceb62e7 100644 --- a/ext/standard/tests/math/pi_basic.phpt +++ b/ext/standard/tests/math/pi_basic.phpt @@ -7,7 +7,7 @@ precision=14 echo pi(), "\n"; echo M_PI, "\n"; // N.B pi() ignores all specified arguments no error -// messages are produced if arguments are spcified. +// messages are produced if arguments are specified. ?> --EXPECT-- 3.1415926535898 diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 5194eaa0df0e..bc1add5a8af5 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -676,12 +676,14 @@ int php_zip_glob(zend_string *spattern, zend_long flags, zval *return_value) /* /* now catch the FreeBSD style of "no matches" */ if (!globbuf.gl_pathc || !globbuf.gl_pathv) { + php_globfree(&globbuf); return 0; } /* we assume that any glob pattern will match files from one directory only so checking the dirname of the first match should be sufficient */ if (ZIP_OPENBASEDIR_CHECKPATH(globbuf.gl_pathv[0])) { + php_globfree(&globbuf); return -1; } diff --git a/ext/zip/tests/gh21698.phpt b/ext/zip/tests/gh21698.phpt new file mode 100644 index 000000000000..d77b2152e72f --- /dev/null +++ b/ext/zip/tests/gh21698.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21698 (ZipArchive::addGlob memory leak when open_basedir rejects the match) +--EXTENSIONS-- +zip +--FILE-- +open($zipfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); + +ini_set('open_basedir', '/nonexistent_dir_for_gh21698'); +var_dump($zip->addGlob(__FILE__, 0, [])); +$zip->close(); +?> +--CLEAN-- + +--EXPECTF-- +Warning: ZipArchive::addGlob(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d +bool(false)