Fix bounds check in multibyte UTF detection - #23527
Open
ydah wants to merge 1 commit into
Open
Conversation
LamentXU123
approved these changes
Sep 1, 2026
Member
There was a problem hiding this comment.
Nice follow-up you can do in this PR: p+wchar_size-1 is not certainly the correct place to read.
Also, please target this PR to 8.4. Otherwise looks good.
Contributor
Author
There was a problem hiding this comment.
Thank you! I updated the endianness detection loop to ensure that a full wide character remains before reading p + wchar_size - 1. I also rebased the branch onto PHP 8.4 and retargeted the PR accordingly.
ydah
requested review from
Girgias,
SakiTakamachi,
TimWolla,
adoy,
arnaud-lb,
dstogov and
kocsismate
as code owners
September 1, 2026 14:21
ydah
force-pushed
the
fix/multibyte-utf-detection-bounds
branch
from
September 1, 2026 14:27
90dc964 to
52a113c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
zend_multibyte_detect_utf_encoding()advances the search position by four bytes after each NUL while looking for UTF-32-specific byte orders. When fewer than three bytes remain,script_size - (p - script) - 2underflows and passes a hugesize_tvalue tomemchr().Scripts are normally backed by a buffer with
ZEND_MMAP_AHEADzero padding, so this generally does not crash. Instead,memchr()may find a NUL in the padding and misdetect a BOM-less UTF-16 script as UTF-32, corrupting the script during conversion whenzend.multibyteis enabled.Track the search position as an offset and call
memchr()only while at least three bytes remain. This also avoids advancing a pointer beyond the script buffer.For example, with
zend.multibyte=1andinternal_encoding=UTF-8:Expected
The 10-byte BOM-less UTF-16LE script is detected as UTF-16LE.
Actual
After the search reaches offset 9, the length calculation underflows.
memchr()finds a NUL in the trailing padding, causing the script to be misdetected as UTF-32LE.