Skip to content

Compiler: fix substr() negative offset on FuncCall haystack (#17572)#17578

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-17572-substr-negative-offset-funccall
Jul 10, 2026
Merged

Compiler: fix substr() negative offset on FuncCall haystack (#17572)#17578
PurHur merged 1 commit into
masterfrom
agent/issue-17572-substr-negative-offset-funccall

Conversation

@PurHur

@PurHur PurHur commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • Generalize substr(f(...), -N) inline producer wiring from sprintf-only to any nested FuncCall haystack (dechex, str_pad, etc.)
  • Extract substrNestedHaystackFuncCallAtUnaryMinusPattern + shared EXEC_RETURN slot resolver
  • Add compliance .phpt guard and unit test for dechex haystack

Closes #17572

Root cause

wireSubstrNestedSprintfCallArgSlot / rewireSubstrNestedSprintfArgSendSlots hard-coded sprintf as the nested callee. substr(dechex(255), -2) wired both ARG_SEND slots to the offset literal (-2) instead of the dechex EXEC_RETURN.

php-src reference

ext/standard/string.cPHP_FUNCTION(substr) negative offset on dynamic string operand

Verification

./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_substr_sprintf_nested.php'
# exit 0

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter "testSubstrNestedDechexUsesFuncCallProducerSlot|substr_negative_offset_funccall|substr_nested_builtin_arg"'
# OK (5 tests, 9 assertions)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter InlineCallArgProducerSlotTest::testSubstr'
# OK (5 tests, 20 assertions)

./script/ci-fast.sh
# exit 0

Made with Cursor

Generalize nested FuncCall + UnaryMinus producer wiring beyond sprintf so
dechex/str_pad haystacks reach substr arg #0 instead of leaking the offset.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit d3acd76 into master Jul 10, 2026
1 check failed
@PurHur
PurHur deleted the agent/issue-17572-substr-negative-offset-funccall branch July 10, 2026 07:24
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: substr() negative offset on FuncCall haystack — returns offset literal not slice (ext/standard/string.c)

1 participant