From d8aa7b9f5d3dcd841b4717747f080901cb6e59d5 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 18 Feb 2025 21:10:00 +0000 Subject: [PATCH 1/2] ext/standard: pathinfo() check flags argument validity. --- ext/standard/string.c | 5 +++++ ext/standard/tests/strings/pathinfo.phpt | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ext/standard/string.c b/ext/standard/string.c index b15a24a098faa..e2a1e5e33ca48 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1587,6 +1587,11 @@ PHP_FUNCTION(pathinfo) Z_PARAM_LONG(opt) ZEND_PARSE_PARAMETERS_END(); + if (opt < PHP_PATHINFO_DIRNAME || opt > PHP_PATHINFO_ALL) { + zend_argument_value_error(2, "must be one of the PATHINFO_* constants"); + RETURN_THROWS(); + } + have_basename = (opt & PHP_PATHINFO_BASENAME); array_init(&tmp); diff --git a/ext/standard/tests/strings/pathinfo.phpt b/ext/standard/tests/strings/pathinfo.phpt index 2bbea73588cb2..530c577f417f4 100644 --- a/ext/standard/tests/strings/pathinfo.phpt +++ b/ext/standard/tests/strings/pathinfo.phpt @@ -23,6 +23,17 @@ var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME)); var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME)); +try { + pathinfo(__FILE__, PATHINFO_DIRNAME-1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_ALL+1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + echo "Done\n"; ?> --EXPECTF-- @@ -102,4 +113,6 @@ string(%d) "%s%estrings" string(12) "pathinfo.php" string(%d) "%s%estrings" string(%d) "%s%estrings" +pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants Done From e66b5e603b8ac7f3f4bbb9530e14cd005b51e2d4 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 23 Feb 2025 23:27:57 +0000 Subject: [PATCH 2/2] forbids flags combinations. --- ext/standard/string.c | 5 ++ .../tests/file/pathinfo_variation3.phpt | 52 ++++++++++++------ ext/standard/tests/strings/pathinfo.phpt | 53 +++++++++++++------ 3 files changed, 78 insertions(+), 32 deletions(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index e2a1e5e33ca48..dabbb2bafe118 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1592,6 +1592,11 @@ PHP_FUNCTION(pathinfo) RETURN_THROWS(); } + if (opt < PHP_PATHINFO_ALL && (opt & (opt - 1))) { + zend_argument_value_error(2, "must be only one of the PATHINFO_* constants"); + RETURN_THROWS(); + } + have_basename = (opt & PHP_PATHINFO_BASENAME); array_init(&tmp); diff --git a/ext/standard/tests/file/pathinfo_variation3.phpt b/ext/standard/tests/file/pathinfo_variation3.phpt index aa1494b57997f..86f88677d813c 100644 --- a/ext/standard/tests/file/pathinfo_variation3.phpt +++ b/ext/standard/tests/file/pathinfo_variation3.phpt @@ -15,15 +15,37 @@ var_dump(pathinfo($testfile, PATHINFO_BASENAME)); var_dump(pathinfo($testfile, PATHINFO_FILENAME)); var_dump(pathinfo($testfile, PATHINFO_EXTENSION)); var_dump(pathinfo($testfile, PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); -var_dump(pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_BASENAME)); +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_EXTENSION); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} ?> --EXPECTF-- @@ -62,11 +84,9 @@ string(6) "inet.h" string(4) "inet" string(1) "h" string(17) "/usr/include/arpa" -string(17) "/usr/include/arpa" -string(6) "inet.h" -string(1) "h" -string(6) "inet.h" -string(17) "/usr/include/arpa" -string(6) "inet.h" -string(17) "/usr/include/arpa" -string(17) "/usr/include/arpa" +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants diff --git a/ext/standard/tests/strings/pathinfo.phpt b/ext/standard/tests/strings/pathinfo.phpt index 530c577f417f4..1ff42a66121cc 100644 --- a/ext/standard/tests/strings/pathinfo.phpt +++ b/ext/standard/tests/strings/pathinfo.phpt @@ -14,14 +14,37 @@ var_dump(pathinfo(__FILE__, PATHINFO_BASENAME)); var_dump(pathinfo(__FILE__, PATHINFO_FILENAME)); var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION)); var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); -var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME)); + +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} try { pathinfo(__FILE__, PATHINFO_DIRNAME-1); @@ -105,14 +128,12 @@ string(12) "pathinfo.php" string(8) "pathinfo" string(3) "php" string(%d) "%s%estrings" -string(%d) "%s%estrings" -string(12) "pathinfo.php" -string(3) "php" -string(12) "pathinfo.php" -string(%d) "%s%estrings" -string(12) "pathinfo.php" -string(%d) "%s%estrings" -string(%d) "%s%estrings" +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants Done