Commit 8ba59c8b5f2 for php
commit 8ba59c8b5f28579420a84fb9c0a4bace4ecf6c63
Author: Weilin Du <weilindu@php.net>
Date: Tue Nov 3 21:02:09 2026 +0800
ext/standard: Reject NUL bytes in version_compare() arguments
diff --git a/NEWS b/NEWS
index 4cc663d5a7e..e25c7e87a93 100644
--- a/NEWS
+++ b/NEWS
@@ -158,6 +158,8 @@ PHP NEWS
- Standard:
. Fixed quoted_printable_decode() truncating input at NUL bytes. (Weilin Du)
+ . Fixed version_compare() silently truncating version strings at NUL bytes by
+ rejecting such input. (Weilin Du)
. Fixed bug #60110 (fclose(), file_put_contents(), copy() do not return false
properly). (Jakub Zelenka, Ilija Tovilo)
. Fixed three Windows-only proc_open() defects: an uninitialized
diff --git a/ext/standard/tests/versioning/version_compare_null_bytes.phpt b/ext/standard/tests/versioning/version_compare_null_bytes.phpt
new file mode 100644
index 00000000000..3a110f7cace
--- /dev/null
+++ b/ext/standard/tests/versioning/version_compare_null_bytes.phpt
@@ -0,0 +1,26 @@
+--TEST--
+version_compare() rejects NUL bytes in version strings
+--FILE--
+<?php
+foreach ([
+ ["1.0\0suffix", '1.0'],
+ ['1.0', "1.0\0suffix"],
+ ["\0", '1.0'],
+ ['1.0', "\0"],
+] as [$version1, $version2]) {
+ try {
+ version_compare($version1, $version2, 'eq');
+ } catch (ValueError $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+ }
+}
+var_dump(version_compare('1.0', '1.0'));
+var_dump(version_compare('1.0', '1.0', 'eq'));
+?>
+--EXPECT--
+ValueError: version_compare(): Argument #1 ($version1) must not contain any null bytes
+ValueError: version_compare(): Argument #2 ($version2) must not contain any null bytes
+ValueError: version_compare(): Argument #1 ($version1) must not contain any null bytes
+ValueError: version_compare(): Argument #2 ($version2) must not contain any null bytes
+int(0)
+bool(true)
diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c
index 33d89167114..2a51f66449c 100644
--- a/ext/standard/versioning.c
+++ b/ext/standard/versioning.c
@@ -215,8 +215,8 @@ PHP_FUNCTION(version_compare)
int compare;
ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STRING(v1, v1_len)
- Z_PARAM_STRING(v2, v2_len)
+ Z_PARAM_PATH(v1, v1_len)
+ Z_PARAM_PATH(v2, v2_len)
Z_PARAM_OPTIONAL
Z_PARAM_STR_OR_NULL(op)
ZEND_PARSE_PARAMETERS_END();