Skip to content

Regression: str_contains()/str_starts_with()/str_ends_with() — Stringable haystack TypeError not __toString coerce (re-#15069, ext/standard/string.c) #16925

Closed

Description

@PurHur

Category

stdlib · php-src-strict · string search builtins

Problem

Zend coerces Stringable objects passed as the haystack argument to str_contains(), str_starts_with(), and str_ends_with() via __toString() before the substring search. The VM raises TypeError: Argument #1 ($haystack) must be of type string, object given.

Verified 2026-07-06 on master.

Repro Zend 8.2+ VM (2026-07-06)
str_contains(new C(), 'obj') where C::__toString(): string true TypeError on haystack type

php-src reference

PHP implementation target

  • ext/standard/str_contains.php (and starts/ends variants) — coerce haystack via shared VmString::coerceStringBuiltinArg() / JitStringBuiltinArg
  • Reuse existing Stringable coercion guards used by other string builtins; VM + JIT/AOT must agree

Repro

./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_str_contains_object_stringable.php'
# Fatal TypeError on str_contains() line — Zend prints true/false/false

Done when

  • str_contains / str_starts_with / str_ends_with accept Stringable haystack on VM/JIT/AOT (php-src-strict)
  • Non-Stringable objects still TypeError like Zend
  • Compliance .phpt guard under test/compliance/cases/stdlib/str_contains_stringable_*.phpt
  • php-src-strict; no php-compiler-strict shortcut

(re-#15069 / #11398 — closed but repro red on master)

Activity

  1. added
    bugSomething isn't working
    enhancementNew feature or request
    phase-4:stdlibPhase 4 – stdlib for web apps
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Jul 6, 2026
  2. PurHur commented on Jul 6, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

  3. PurHur commented on Jul 6, 2026

    @PurHur
    OwnerAuthor

    claim released: repro matches Zend on master — with declare(strict_types=1) both Zend 8.2 and VM throw TypeError; without strict_types both coerce Stringable via __toString (truetruetrue). Issue expectation contradicts php-src-strict. Pivoting to #16926.

  4. PurHur commented on Jul 6, 2026

    @PurHur
    OwnerAuthor

    Maintainer triage 2026-07-06: repro on master still matches Zend 8.2 — strict_types TypeError vs coerce per prior release comment. Recommend close as stale / mis-scoped unless retargeted to a concrete php-src divergence with a fresh repro table.

  5. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

  6. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim released: repro has declare(strict_types=1) — both Zend 8.2 and VM throw TypeError; without strict_types both coerce Stringable (truetruetrue). Stale per prior triage.

  7. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run

  8. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim released: repro matches Zend 8.2 — both coerce Stringable haystack without strict_types; both TypeError with declare(strict_types=1). Issue stale.

  9. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run (str_contains Stringable haystack coercion)

  10. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

  11. PurHur commented on Jul 7, 2026

    @PurHur
    OwnerAuthor

    claim released: repro uses declare(strict_types=1) — Zend 8.2 also throws TypeError for str_contains(new C(), ...) under strict_types; without strict_types both VM and Zend print true. Issue stale vs php-src-strict. Pivoting.

  12. PurHur commented on Jul 9, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run

  13. PurHur commented on Jul 9, 2026

    @PurHur
    OwnerAuthor

    claim released: repro uses declare(strict_types=1) — Zend 8.2 also TypeError; non-strict path green via str_contains_stringable_coerce.phpt. Issue stale. Pivoting.

  14. PurHur commented on Jul 10, 2026

    @PurHur
    OwnerAuthor

    Triage (advanced stdlib 2026-07-10): maintainer_gap_str_contains_object_stringable.php throws TypeError on both Zend 8.2.31 and VM — php-src-strict parity already holds. Recommend close or re-scope if a newer php-src branch changed Stringable haystack coercion.

  15. PurHur commented on Jul 11, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib Advanced — batch (issues #17821, #16937, #16925)

  16. PurHur commented on Jul 11, 2026

    @PurHur
    OwnerAuthor

    Merged via #17850. Verification: maintainer_gap_str_contains_object_stringable.php → truetruetrue; compliance str_contains_stringable_haystack.phpt green; VM+JIT via JitStringBuiltinArg::lowerCoercible(..., allowStringableUnderStrict: true).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machinebugSomething isn't workingenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsstdlib

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions