test(count): lock the null-container sentinel path after the #585 normalization - #616
Conversation
|
The remaining count() parity gap mentioned in the description (non-null scalars in a mixed cell silently counting as 0, where PHP raises TypeError with the scalar type in the message) is now tracked as #617 — the machinery from this PR makes it a small follow-up, but it changes a test-locked behavior so it's kept separate. |
|
CI caught a real interaction here: extending the TypeError to plain null receivers breaks the deliberate BUG-0 CLI convention that off-web superglobals count as 0 ( |
|
Correction pushed ( |
…tudio#585 normalization count() on a Mixed receiver carrying the null-container sentinel used to dereference it and segfault (issue illegalstudio#602). The normalization added for issue illegalstudio#585 turns that sentinel into a real null before count() sees it, so the crash is gone on main without a dedicated guard. These tests lock the resulting behavior: the sentinel path no longer crashes, reports the missed read and counts as 0, and stays heap-clean; a real null cell counts the same way; a populated merge and an empty container are unaffected. One test records that no TypeError is raised where PHP raises one, so the divergence tracked in issue illegalstudio#617 cannot be changed silently. Claude-Session: https://claude.ai/code/session_01124pGFSEbzYQcGbNykWN7V
ac606f3 to
6d88381
Compare
|
This PR no longer needs to change any runtime code — your #585 normalization already fixed #602. I've rewritten it as tests only and retitled it accordingly. Rebasing it onto today's So I checked whether the original crash still exists. On $rows = [[1, 2]];
$r = $argc == 1 ? $rows[5] : ["a", "b"];
echo count($r), "\n";Normalization turns the sentinel into a real null before What remains is the PHP-parity gap: The six tests lock what Verified on |
Summary
count()on a boxedMixedreceiver whose payload was the null-container sentinel used tosegfault (exit 139). A missed array read forwarded through a ternary merge
(
$argc == 1 ? $rows[5] : ["a", "b"]) was the concrete repro from issue #602.That crash is already gone on
main: the null-container normalization from issue #585(PR #591) turns the sentinel into a real null before
count()ever sees it, and__rt_mixed_countalready guards tag-4/5 payloads withemit_branch_if_null_container.There is no dedicated runtime change left for this PR to land — an earlier guard here became
unreachable after rebasing onto that normalization.
This PR is tests only. It locks the post-#585 behavior so the #602 crash cannot return
silently, and it records the remaining PHP-parity gap so #617 cannot be changed by accident.
Observed behavior (locked here)
Run with no arguments (missed-read arm):
Warning: Undefined array key 5, then SIGSEGV (exit 139).main/ this PR: the same warning, then0(exit 0) — no crash.TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given.The quiet
0for null receivers also preserves the off-web BUG-0 convention(
count($_SERVER) === 0before assignment). Closing the PHP TypeError gap without breakingthat convention is tracked separately in #617. After normalization, sentinel and real null
are no longer distinguishable at
count(), so #617 is an all-or-nothing decision.Tests
New regression file
tests/codegen/regressions/mixed_count_sentinel.rs:count()does not crash; prints0and the undefined-key warningcatch (TypeError)does not fire (explicit count() on mixed null/scalar receivers returns 0 instead of PHP's TypeError #617 divergence lock)json_decode("null"), tag 8) counts as0the same waymixedcell still counts as0without a warningNon-goals
Fixes #602