Commit 35d9eac27b8 for php

commit 35d9eac27b8d66f474dddab189c593a11e473736
Author: lazerg <lazerg2@gmail.com>
Date:   Thu Oct 22 06:23:49 2026 +0500

    Fix GH-24489: Restore mbstring buffer growth fix lost in merge

diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h
index 6abc042ff09..e71737318bf 100644
--- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h
+++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h
@@ -170,6 +170,9 @@ static inline zend_result mb_convert_buf_ensure(mb_convert_buf *buf, unsigned ch
 		size_t newsize = oldsize + MAX(oldsize >> 1, needed);
 		zend_string *newstr = safe_ferealloc((buf)->str, 1, newsize, _ZSTR_STRUCT_SIZE(0), /* fallible */ true);
 		if (!newstr) {
+			/* An earlier growth may have moved the buffer. */
+			buf->out = *out;
+			buf->limit = *limit;
 			return FAILURE;
 		}
 		*out = (unsigned char*)ZSTR_VAL(newstr) + (*out - (unsigned char*)ZSTR_VAL((buf)->str));
diff --git a/ext/mbstring/tests/oom_buf_growth.phpt b/ext/mbstring/tests/oom_buf_growth.phpt
new file mode 100644
index 00000000000..928776c6399
--- /dev/null
+++ b/ext/mbstring/tests/oom_buf_growth.phpt
@@ -0,0 +1,28 @@
+--TEST--
+mbstring stores conversion-buffer pointers when growth fails
+--EXTENSIONS--
+mbstring
+--INI--
+memory_limit=8M
+--SKIPIF--
+<?php
+// This regression test was written to cover a memory-corruption bug, but it only
+// actually detects the bug when we run the test under a memory sanitizer like ASan.
+if (!getenv('SKIP_ASAN')) {
+    die('skip only discriminates under an ASan-instrumented build');
+}
+if (PHP_INT_SIZE !== 8) {
+    die('skip 64-bit only');
+}
+?>
+--FILE--
+<?php
+// A single batch expands from 128 to 384 bytes, requiring two buffer growths.
+$input = str_repeat("\x80", 128);
+// The tracked allocator leaves enough space for the first growth, but not the second.
+$padding = str_repeat('a', 8 * 1024 * 1024 - memory_get_usage() - 384);
+mb_substr_count($input, 'Z', 'CP1252');
+echo "not reached\n";
+?>
+--EXPECTF--
+Fatal error: Allowed memory size of 8388608 bytes exhausted %S(tried to allocate %d bytes) in %s on line %d