From a5f21ca7005f3825c47d52772ee2f66c6a81cf86 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 22 Jun 2025 10:13:06 +0200 Subject: [PATCH] Fix GH-18901: integer overflow mb_split We prevent signed overflow by making the count unsigned. The actual interpretation of the count doesn't matter as it's just used to denote a limit. The test output for some limit values looks strange though, so that may need extra investigation. However, that's orthogonal to this fix. Closes GH-18906. --- NEWS | 3 ++ ext/mbstring/php_mbregex.c | 2 +- ext/mbstring/tests/gh18901.phpt | 54 +++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 ext/mbstring/tests/gh18901.phpt diff --git a/NEWS b/NEWS index 25706b1efc0..ea77125b205 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ PHP NEWS . Fixed GH-18902 ldap_exop/ldap_exop_sync assert triggered on empty request OID. (David Carlier) +- MbString: + . Fixed bug GH-18901 (integer overflow mb_split). (nielsdos) + - Streams: . Fixed GH-13264 (fgets() and stream_get_line() do not return false on filter fatal error). (Jakub Zelenka) diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 99dc91e34dc..86bc5f61d85 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -1184,7 +1184,7 @@ PHP_FUNCTION(mb_split) size_t string_len; int err; - zend_long count = -1; + zend_ulong count = -1; /* unsigned, it's a limit and we want to prevent signed overflow */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|l", &arg_pattern, &arg_pattern_len, &string, &string_len, &count) == FAILURE) { RETURN_THROWS(); diff --git a/ext/mbstring/tests/gh18901.phpt b/ext/mbstring/tests/gh18901.phpt new file mode 100644 index 00000000000..8d862a537c3 --- /dev/null +++ b/ext/mbstring/tests/gh18901.phpt @@ -0,0 +1,54 @@ +--TEST-- +GH-18901 (integer overflow mb_split) +--EXTENSIONS-- +mbstring +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + string(0) "" +} +array(4) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + string(0) "" +} +array(4) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + string(0) "" +} +array(1) { + [0]=> + string(3) "123" +} +array(1) { + [0]=> + string(3) "123" +}