Skip to content

AOT: mb_substr(null length) and negative start match Zend (#27028 regression) - #34846

Merged
PurHur merged 1 commit into
masterfrom
fix/mb-substr-null-length-aot-27028
Aug 25, 2026
Merged

PurHur merged 1 commit into
masterfrom
fix/mb-substr-null-length-aot-27028

Conversation

@PurHur

@PurHur PurHur commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Recognize compile-time null length via isNullConstant in JitMbSubstr (fold + runtime sentinel path)
  • Normalize negative $start, omitted length (-1 sentinel), and negative $length in MbSubstrJitHelper::substrArgv before the UTF-8 char walk — matches VmMbstring::substr / php-src mb_get_substr

Root cause

#27028 closed while the AOT fixture still failed: explicit mb_substr($s, -2, null) took the NestedJIT path with length -1, but MbSubstrJitHelper computed $endAt = $start + $length without normalizing negative start or treating -1 as "to end". Compile-time fold also skipped null literals because only TYPE_NULL was checked, not isNullConstant.

php-src reference

  • ext/mbstring/mbstring.c — PHP_FUNCTION(mb_substr) / mb_get_substr

Verification

./script/aot-smoke.sh
# aot-smoke: 8 passed, 0 failed

./script/phpunit.sh --filter 'AotTest::testCases with data set "mb_substr"'
# OK (1 test, 5 assertions)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh; … mb_substr("αβγ", -2, null, "UTF-8") …'
# AOT output matches Zend: βγ

Closes #27028

Made with Cursor

…ression)

Explicit null length was not recognized as omitted (isNullConstant gap), and
MbSubstrJitHelper did not normalize negative start/length before the UTF-8 walk.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit 621fd49 into master Aug 25, 2026
1 check failed
@PurHur
PurHur deleted the fix/mb-substr-null-length-aot-27028 branch August 25, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: AOT mb_substr() not lowered — compile fails; VM/JIT match Zend (ext/mbstring/mbstring.c)

1 participant