Skip to content

Leave no placeholder or empty entry in payload masks - #42

Merged
nicolas-grekas merged 1 commit into
mainfrom
clean-masks
Sep 23, 2026
Merged

nicolas-grekas merged 1 commit into
mainfrom
clean-masks

Conversation

@nicolas-grekas

Copy link
Copy Markdown
Member

deepclone_to_array() stripped the null placeholders left by unwrapping references seen once from the top-level mask only: property, __unserialize() state and shared ref masks kept them. Shared references to scalars also left an undefined entry in refMasks, which count() sees but iteration doesn't:

$v = [1];
$v[] = &$v[0];
deepclone_to_array($v)['refMasks']; // array(1) {}, now unset

Payloads are now identical to the polyfill's, which I checked on the reference cases covered by symfony/polyfill#674.

Unwrapping the references seen once clears their mask slots to NULL, which
dc_mask_cleanup() then strips, but only from the top-level mask: property,
__unserialize() state and shared ref masks kept those placeholders. Clean
them all after the unwrap pass.

Shared references to scalars also added their UNDEF mask to refMasks,
leaving an array that count() sees one element in but that iterates empty.
Skip masks that are UNDEF as well as NULL.
@nicolas-grekas
nicolas-grekas merged commit 3ec183f into main Sep 23, 2026
21 checks passed
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.

1 participant