Fix serialize() object lifetime across nested callbacks#22689
Open
PuH4ck3rX wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
php_add_var_hash() skipped uniquely owned objects when the current class had no __serialize() or __sleep() method. However, serializing one of that object's properties can invoke a nested magic callback. The callback may release the current object while its declared-property slots are still being traversed, leaving the serializer with stale zval pointers.
The skipped object was also absent from the serialization identity table. A temporary local reference would prevent destruction but would not preserve reference semantics if a nested callback made the object reachable again. This change removes the unsafe RC1 fast path so objects are retained and registered for the full serialization operation.
The regression test deterministically replaces the released object with a same-layout object. Before the fix, serialize() emits the replacement string under the victim property name; after the fix, it preserves the original integer value.
Checks performed: