[php-src] PR #25167: Fix GH-23106 / GH-25025: Clamp pos in offset_to_pointer_utf8 to prevent out-of-bounds read on truncated UTF-8

From: Date: Mon, 02 Nov 2026 21:15:59 +0000
Subject: [php-src] PR #25167: Fix GH-23106 / GH-25025: Clamp pos in offset_to_pointer_utf8 to prevent out-of-bounds read on truncated UTF-8
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-40249@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/25167 Author: AdamMagued Fixes GH-25025 and GH-23106 for the PHP-8.3 branch. Backport of master/8.4 commit cc22056f9d (PR #23107, credited to Lazizbek Ergashev), which resolved GH-23106 in 8.4.27 and 8.5.12. ### Root Cause In ext/mbstring/mbstring.c, offset_to_pointer_utf8() walks the haystack forward using mbfl_encoding_utf8.mblen_table: ```c const unsigned char *u8_tbl = mbfl_encoding_utf8.mblen_table; unsigned char *pos = str; while (offset-- > 0) { if (pos >= end) { return NULL; } pos += u8_tbl[*pos]; } return pos; ``` When str ends in a truncated multi-byte sequence (such as \xf0\x90), u8_tbl[*pos] advances pos by the full expected sequence length (4 bytes) rather than the remaining bytes in the buffer. The function then returns a pointer beyond end. When callers like zend_memnstr() or zend_memnrstr() receive this pointer: 1. Debug builds fail the assert(end >= p) invariant check in zend_operators.h. 2. Release builds perform an out-of-bounds read (CWE-125) past the haystack buffer, returning non-deterministic offsets or segfaulting on long inputs. ### Fix Add the clamp if (pos > end) { pos = end; } identical to master/8.4 before returning pos. ### Regression Test Ported and extended regression test in ext/mbstring/tests/gh23106.phpt verifying truncated UTF-8 haystacks with positive and negative offsets under mb_strpos() and mb_strrpos(). ### Verification - Pre-fix: gh23106.phpt reproduces the out-of-bounds read (mb_strpos("AA\xf0\x90", "x", 3) returns int(29) instead of bool(false)). - Post-fix: gh23106.phpt passes cleanly. - Full ext/mbstring test suite in container sandbox: 416 passed, 0 failed, 9 skipped.

« previous php.git-pulls (#40249) next »