Commit 2f404e73fc7 for php
commit 2f404e73fc7bd8d7d112dfbc0df9eaedb832fd03
Author: Marc Bennewitz <marc-mabe@users.noreply.github.com>
Date: Mon Nov 2 16:32:07 2026 +0100
Fix ZEND_LONG_UINT_OVFL() accepting negative values on 32-bit platforms (#24778)
Where zend_long is not wider than an int, ZEND_LONG_UINT_OVFL() was
defined as 0, so a negative value passed the check there, while it is
rejected where zend_long is wider. Keep checking the lower bound on these
platforms too.
This affects mbstring.regex_stack_limit, mbstring.regex_retry_limit and
the codepage of sapi_windows_cp_set() and sapi_windows_cp_conv().
diff --git a/NEWS b/NEWS
index daf52ae14d9..0dbd1376328 100644
--- a/NEWS
+++ b/NEWS
@@ -139,6 +139,8 @@ PHP NEWS
. Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela)
. Fixed out-of-bounds read in php_mb_rfc1867_getword() on a multibyte lead
byte at the end of a multipart field name. (Jorg Sowa)
+ . Fixed negative mbstring.regex_stack_limit and mbstring.regex_retry_limit
+ on 32bit platforms. (Marc Bennewitz)
- MySQLnd:
. Fixed bug GH-24293 (Segfault on connect with an empty password to a
@@ -333,6 +335,8 @@ PHP NEWS
tidy::repairFile() rejecting null for $encoding. (lacatoire)
- Windows:
+ . Fixed sapi_windows_cp_set() and sapi_windows_cp_conv() accepting a negative
+ codepage on 32bit platforms. (Marc Bennewitz)
. Fixed bug GH-25009 (GetConsoleTitleW() buffer size passed in bytes).
(Lazizbek Ergashev)
diff --git a/Zend/zend_range_check.h b/Zend/zend_range_check.h
index 9c822493fa3..70caaf78f9d 100644
--- a/Zend/zend_range_check.h
+++ b/Zend/zend_range_check.h
@@ -47,7 +47,7 @@
# define ZEND_LONG_INT_OVFL(zl) (0)
# define ZEND_LONG_INT_UDFL(zl) (0)
# define ZEND_LONG_EXCEEDS_INT(zlong) (0)
-# define ZEND_LONG_UINT_OVFL(zl) (0)
+# define ZEND_LONG_UINT_OVFL(zl) UNEXPECTED((zl) < 0)
#endif
/* size_t vs (unsigned) int checks. */
diff --git a/ext/mbstring/tests/retry_limit_negative.phpt b/ext/mbstring/tests/retry_limit_negative.phpt
new file mode 100644
index 00000000000..b498a7463d2
--- /dev/null
+++ b/ext/mbstring/tests/retry_limit_negative.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Oniguruma retry limit is not set from a negative mbstring.regex_retry_limit
+--EXTENSIONS--
+mbstring
+--SKIPIF--
+<?php
+if (!function_exists('mb_ereg')) die('skip mb_ereg not available');
+if (@version_compare(MB_ONIGURUMA_VERSION, '6.9.3') < 0) {
+ die('skip requires Oniguruma >= 6.9.3');
+}
+?>
+--INI--
+error_reporting=E_ALL & ~E_DEPRECATED
+mbstring.regex_retry_limit=-1
+--FILE--
+<?php
+/* A negative limit must leave the default of Oniguruma in place, rather than
+ * being converted to an unsigned int of UINT_MAX. This match needs more
+ * retries than the default allows for. */
+$regex = 'A(B|C+)+D|AC+X';
+$str = 'A' . str_repeat('C', 24) . 'X';
+var_dump(mb_ereg($regex, $str));
+?>
+--EXPECT--
+bool(false)
diff --git a/ext/standard/tests/strings/sapi_windows_cp_negative_codepage.phpt b/ext/standard/tests/strings/sapi_windows_cp_negative_codepage.phpt
new file mode 100644
index 00000000000..997685f34ef
--- /dev/null
+++ b/ext/standard/tests/strings/sapi_windows_cp_negative_codepage.phpt
@@ -0,0 +1,37 @@
+--TEST--
+sapi_windows_cp_set() and sapi_windows_cp_conv() must reject a negative codepage
+--SKIPIF--
+<?php
+if (PHP_OS_FAMILY !== 'Windows') die('skip for Windows only');
+?>
+--FILE--
+<?php
+try {
+ sapi_windows_cp_set(-1);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+ sapi_windows_cp_set(PHP_INT_MIN);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+ sapi_windows_cp_conv(-1, 65001, 'php');
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+ sapi_windows_cp_conv(65001, -1, 'php');
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+ValueError: sapi_windows_cp_set(): Argument #1 ($codepage) must be between 0 and 4294967295
+ValueError: sapi_windows_cp_set(): Argument #1 ($codepage) must be between 0 and 4294967295
+ValueError: sapi_windows_cp_conv(): Argument #1 ($in_codepage) must be between 0 and 4294967295
+ValueError: sapi_windows_cp_conv(): Argument #2 ($out_codepage) must be between 0 and 4294967295