From 7bc7a80445f2bb349891d3cccfef2d589c48607e Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Wed, 2 Dec 2020 10:21:08 +0100 Subject: [PATCH] Make is_file() and friends return false when path contains 0-byte These functions now return false silently: is_writable, is_readable, is_executable, is_file, is_dir, is_link, file_exists These functions now throw a warning an return false (rather than throwing a ValueError): fileperms, fileinode, filesize, fileowner, filegroup, filetype, fileatime, filemtime, filectime, lstat, stat See also https://externals.io/message/112333. Closes GH-6478. --- ext/standard/filestat.c | 7 +++++-- ext/standard/tests/file/bug39863.phpt | 9 ++------- ext/standard/tests/file/filegroup_variation3.phpt | 8 ++++++-- ext/standard/tests/file/fileinode_variation3.phpt | 8 ++++++-- ext/standard/tests/file/fileowner_variation3.phpt | 8 ++++++-- ext/standard/tests/file/fileperms_variation3.phpt | 8 ++++++-- ext/standard/tests/file/is_dir_variation4.phpt | 4 ++-- .../tests/file/is_executable_variation1.phpt | 4 ++-- ext/standard/tests/file/is_file_variation4.phpt | 4 ++-- ext/standard/tests/file/is_readable_variation1.phpt | 6 +++--- ext/standard/tests/file/is_writable_variation1.phpt | 12 ++++++------ 11 files changed, 46 insertions(+), 32 deletions(-) diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 61546c3da6..303e919c19 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -728,7 +728,10 @@ PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zva const char *local; php_stream_wrapper *wrapper; - if (!filename_length) { + if (!filename_length || CHECK_NULL_PATH(filename, filename_length)) { + if (filename_length && !IS_EXISTS_CHECK(type)) { + php_error_docref(NULL, E_WARNING, "Filename contains null byte"); + } RETURN_FALSE; } @@ -937,7 +940,7 @@ ZEND_NAMED_FUNCTION(name) { \ size_t filename_len; \ \ ZEND_PARSE_PARAMETERS_START(1, 1) \ - Z_PARAM_PATH(filename, filename_len) \ + Z_PARAM_STRING(filename, filename_len) \ ZEND_PARSE_PARAMETERS_END(); \ \ php_stat(filename, filename_len, funcnum, return_value); \ diff --git a/ext/standard/tests/file/bug39863.phpt b/ext/standard/tests/file/bug39863.phpt index c69cb6d0a6..88c569473a 100644 --- a/ext/standard/tests/file/bug39863.phpt +++ b/ext/standard/tests/file/bug39863.phpt @@ -6,12 +6,7 @@ Andrew van der Stock, vanderaj @ owasp.org getMessage(), "\n"; -} +var_dump(file_exists($filename)); ?> --EXPECT-- -file_exists(): Argument #1 ($filename) must not contain any null bytes +bool(false) diff --git a/ext/standard/tests/file/filegroup_variation3.phpt b/ext/standard/tests/file/filegroup_variation3.phpt index d18da05855..e844be0772 100644 --- a/ext/standard/tests/file/filegroup_variation3.phpt +++ b/ext/standard/tests/file/filegroup_variation3.phpt @@ -75,8 +75,12 @@ bool(false) Warning: filegroup(): stat failed for %s/filegroup_variation3/filegroup*.tmp in %s on line %d bool(false) - Iteration 7 - -filegroup(): Argument #1 ($filename) must not contain any null bytes + +Warning: filegroup(): Filename contains null byte in %s on line %d +bool(false) - Iteration 8 - -filegroup(): Argument #1 ($filename) must not contain any null bytes + +Warning: filegroup(): Filename contains null byte in %s on line %d +bool(false) *** Done *** diff --git a/ext/standard/tests/file/fileinode_variation3.phpt b/ext/standard/tests/file/fileinode_variation3.phpt index 1158308687..92357a3619 100644 --- a/ext/standard/tests/file/fileinode_variation3.phpt +++ b/ext/standard/tests/file/fileinode_variation3.phpt @@ -74,8 +74,12 @@ bool(false) Warning: fileinode(): stat failed for %s/fileinode_variation3/fileinode*.tmp in %s on line %d bool(false) - Iteration 7 - -fileinode(): Argument #1 ($filename) must not contain any null bytes + +Warning: fileinode(): Filename contains null byte in %s on line %d +bool(false) - Iteration 8 - -fileinode(): Argument #1 ($filename) must not contain any null bytes + +Warning: fileinode(): Filename contains null byte in %s on line %d +bool(false) *** Done *** diff --git a/ext/standard/tests/file/fileowner_variation3.phpt b/ext/standard/tests/file/fileowner_variation3.phpt index a61b0ab0a3..63ba6936aa 100644 --- a/ext/standard/tests/file/fileowner_variation3.phpt +++ b/ext/standard/tests/file/fileowner_variation3.phpt @@ -75,8 +75,12 @@ bool(false) Warning: fileowner(): stat failed for %s/fileowner_variation3/fileowner*.tmp in %s on line %d bool(false) - Iteration 7 - -fileowner(): Argument #1 ($filename) must not contain any null bytes + +Warning: fileowner(): Filename contains null byte in %s on line %d +bool(false) - Iteration 8 - -fileowner(): Argument #1 ($filename) must not contain any null bytes + +Warning: fileowner(): Filename contains null byte in %s on line %d +bool(false) *** Done *** diff --git a/ext/standard/tests/file/fileperms_variation3.phpt b/ext/standard/tests/file/fileperms_variation3.phpt index ada750bbab..5e981e9b86 100644 --- a/ext/standard/tests/file/fileperms_variation3.phpt +++ b/ext/standard/tests/file/fileperms_variation3.phpt @@ -74,8 +74,12 @@ bool(false) Warning: fileperms(): stat failed for %s/fileperms_variation3/fileperms*.tmp in %s on line %d bool(false) - Iteration 7 - -fileperms(): Argument #1 ($filename) must not contain any null bytes + +Warning: fileperms(): Filename contains null byte in %s on line %d +bool(false) - Iteration 8 - -fileperms(): Argument #1 ($filename) must not contain any null bytes + +Warning: fileperms(): Filename contains null byte in %s on line %d +bool(false) *** Done *** diff --git a/ext/standard/tests/file/is_dir_variation4.phpt b/ext/standard/tests/file/is_dir_variation4.phpt index 8a1563992f..d6e64efe21 100644 --- a/ext/standard/tests/file/is_dir_variation4.phpt +++ b/ext/standard/tests/file/is_dir_variation4.phpt @@ -76,9 +76,9 @@ bool(true) bool(false) -- Iteration 9 -- -is_dir(): Argument #1 ($filename) must not contain any null bytes +bool(false) -- Iteration 10 -- -is_dir(): Argument #1 ($filename) must not contain any null bytes +bool(false) *** Done *** diff --git a/ext/standard/tests/file/is_executable_variation1.phpt b/ext/standard/tests/file/is_executable_variation1.phpt index de08c1d917..a85b9a2ef0 100644 --- a/ext/standard/tests/file/is_executable_variation1.phpt +++ b/ext/standard/tests/file/is_executable_variation1.phpt @@ -76,9 +76,9 @@ bool(false) -- Iteration 5 -- bool(false) -- Iteration 6 -- -is_executable(): Argument #1 ($filename) must not contain any null bytes +bool(false) -- Iteration 7 -- -is_executable(): Argument #1 ($filename) must not contain any null bytes +bool(false) -- Iteration 8 -- bool(false) -- Iteration 9 -- diff --git a/ext/standard/tests/file/is_file_variation4.phpt b/ext/standard/tests/file/is_file_variation4.phpt index f6921d1d87..1afc34dd03 100644 --- a/ext/standard/tests/file/is_file_variation4.phpt +++ b/ext/standard/tests/file/is_file_variation4.phpt @@ -66,8 +66,8 @@ bool(false) - Iteration 6 - bool(false) - Iteration 7 - -is_file(): Argument #1 ($filename) must not contain any null bytes +bool(false) - Iteration 8 - -is_file(): Argument #1 ($filename) must not contain any null bytes +bool(false) *** Done *** diff --git a/ext/standard/tests/file/is_readable_variation1.phpt b/ext/standard/tests/file/is_readable_variation1.phpt index d46e5fa5ca..9c25213f8a 100644 --- a/ext/standard/tests/file/is_readable_variation1.phpt +++ b/ext/standard/tests/file/is_readable_variation1.phpt @@ -77,11 +77,11 @@ bool(false) -- Iteration 6 -- bool(false) -- Iteration 7 -- -is_readable(): Argument #1 ($filename) must not contain any null bytes +bool(false) -- Iteration 8 -- -is_readable(): Argument #1 ($filename) must not contain any null bytes +bool(false) -- Iteration 9 -- -is_readable(): Argument #1 ($filename) must not contain any null bytes +bool(false) -- Iteration 10 -- bool(true) -- Iteration 11 -- diff --git a/ext/standard/tests/file/is_writable_variation1.phpt b/ext/standard/tests/file/is_writable_variation1.phpt index 9361ec947c..80695d6d45 100644 --- a/ext/standard/tests/file/is_writable_variation1.phpt +++ b/ext/standard/tests/file/is_writable_variation1.phpt @@ -87,14 +87,14 @@ bool(false) bool(false) bool(false) -- Iteration 7 -- -is_writable(): Argument #1 ($filename) must not contain any null bytes -is_writeable(): Argument #1 ($filename) must not contain any null bytes +bool(false) +bool(false) -- Iteration 8 -- -is_writable(): Argument #1 ($filename) must not contain any null bytes -is_writeable(): Argument #1 ($filename) must not contain any null bytes +bool(false) +bool(false) -- Iteration 9 -- -is_writable(): Argument #1 ($filename) must not contain any null bytes -is_writeable(): Argument #1 ($filename) must not contain any null bytes +bool(false) +bool(false) -- Iteration 10 -- bool(true) bool(true) -- 2.40.0