From a3cb82bd1b120df4a0344889cbc0f5deb4d315d1 Mon Sep 17 00:00:00 2001 From: lacatoire Date: Tue, 18 Aug 2026 07:14:21 +0200 Subject: [PATCH 1/2] ext/hash: report argument #2 ($filename) for null bytes in hash_file() php_hash_do_hash() hardcodes argument index 1 in the isfilename branch, so hash_file() blames $algo for a null byte carried by $filename. hash_file() is the only caller passing isfilename = 1, and its filename is argument #2; php_hash_do_hash_hmac() already uses 2 for the same check. --- ext/hash/hash.c | 2 +- ext/hash/tests/hash_file_error.phpt | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ext/hash/hash.c b/ext/hash/hash.c index d57ae149691b..4a0b0c49437e 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -361,7 +361,7 @@ static void php_hash_do_hash( } if (isfilename) { if (zend_char_has_nul_byte(data, data_len)) { - zend_argument_value_error(1, "must not contain any null bytes"); + zend_argument_value_error(2, "must not contain any null bytes"); RETURN_THROWS(); } stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, FG(default_context)); diff --git a/ext/hash/tests/hash_file_error.phpt b/ext/hash/tests/hash_file_error.phpt index a381d3bdd63c..6008ce6f5474 100644 --- a/ext/hash/tests/hash_file_error.phpt +++ b/ext/hash/tests/hash_file_error.phpt @@ -19,6 +19,13 @@ try { echo $exception::class, ': ', $exception->getMessage(), "\n"; } +echo "\n-- Testing hash_file() function with a null byte in the filename --\n"; +try { + hash_file('md5', $filename . chr(0) . $filename); +} catch (ValueError $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; +} + echo "\n-- Testing hash_file() function with a non-existent file --\n"; var_dump(hash_file('md5', 'nonexistent.txt')); @@ -36,6 +43,9 @@ unlink( $filename ); -- Testing hash_file() function with an unknown algorithm -- ValueError: hash_file(): Argument #1 ($algo) must be a valid hashing algorithm +-- Testing hash_file() function with a null byte in the filename -- +ValueError: hash_file(): Argument #2 ($filename) must not contain any null bytes + -- Testing hash_file() function with a non-existent file -- Warning: hash_file(): Failed to open stream: No such file or directory in %s on line %d From ee4cbb11dc9141d6476f6cfbf056e3452cc1ff9a Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Tue, 1 Sep 2026 22:30:05 +0200 Subject: [PATCH 2/2] Update ext/hash/tests/hash_file_error.phpt Co-authored-by: NickSdot <32384907+NickSdot@users.noreply.github.com> --- ext/hash/tests/hash_file_error.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/hash/tests/hash_file_error.phpt b/ext/hash/tests/hash_file_error.phpt index 6008ce6f5474..4ef84a62ddf4 100644 --- a/ext/hash/tests/hash_file_error.phpt +++ b/ext/hash/tests/hash_file_error.phpt @@ -22,8 +22,8 @@ try { echo "\n-- Testing hash_file() function with a null byte in the filename --\n"; try { hash_file('md5', $filename . chr(0) . $filename); -} catch (ValueError $exception) { - echo $exception::class, ': ', $exception->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n-- Testing hash_file() function with a non-existent file --\n";