Skip to content

Fix str_contains/str_starts_with/str_ends_with Stringable coercion (#15069) - #15075

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-15069-str-contains-stringable
Jul 2, 2026
Merged

PurHur merged 1 commit into
masterfrom
agent/issue-15069-str-contains-stringable

Conversation

@PurHur

@PurHur PurHur commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Restore Zend __toString coercion for Stringable operands on str_contains(), str_starts_with(), and str_ends_with() when the caller is not strict_types.
  • VM follows the existing strcmp pattern (coerceStringBuiltinArg + InternalStrictArg::requireString under strict); JIT uses JitStringBuiltinArg::lowerCoercible instead of lower / coerceStringBuiltinArgNoObject.

Closes #15069

php-src reference

  • ext/standard/string.c — php_str_contains, php_str_starts_with, php_str_ends_with, zend_parse_arg_str coercion path

Verification

./script/docker-exec.sh -- bash -lc 'cd /compiler && vendor/bin/phpunit --filter str_contains_stringable_coerce'
# OK (2 tests, 2 assertions) — VM + JIT compliance

./script/docker-exec.sh -- php bin/vm.php -r '
class C { public function __toString(): string { return "obj"; } }
var_export(str_contains(new C(), "obj"));
'
# true

./script/docker-exec.sh -- bash -lc 'cd /compiler && php bin/compile.php -l test/compliance/cases/stdlib/str_contains_stringable_coerce.phpt'
# (use inline script) php bin/compile.php -l with StringableObj repro — lint OK

Made with Cursor

Use coerceStringBuiltinArg with caller strict_types parity (strcmp pattern)
instead of coerceStringBuiltinArgNoObject; JIT uses lowerCoercible.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant