Skip to content

Fix RCn array modification violation with ArrayObject serialize #17942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

iluuu1994
Copy link
Member

We seem to be assuming that the ArrayObject has exclusive access to the underlying array value. The existing RC hacks seems peculiar and should be investigated...

Fixes GH-17935

Honestly, not sure if this is worth fixing.

We seem to be assuming that the ArrayObject has exclusive access to the
underlying array value. The existing RC hacks seems peculiar and should
be investigated...

Fixes phpGH-17935
@nielsdos
Copy link
Member

Looks like this changes behaviour. Maybe fix on master with a refactor of the RC checks, doesn't seem too important given how broken this crap is anyway

@Girgias
Copy link
Member

Girgias commented Feb 27, 2025

I don't remember exactly why the RC hacks where done, but they were fixing a bunch of other issues.

@nielsdos
Copy link
Member

nielsdos commented Feb 27, 2025

I assume we refer to this: #10749? It looks completely wrong and might even cause other issues if user code can run at certain points. This issue (i.e. the one from this PR) should be fixed by properly fixing the original issue (i.e. the one referenced in that PR). Note for example that the Bucket pointer can become stale upon array resize...

@Girgias
Copy link
Member

Girgias commented Feb 27, 2025

Yes that's (at least one) of the relevant PRs.

I guess the simplest would be to just always duplicate the HashTable so that we are the sole owner? But that will be bad performance wise I'm guessing.

@nielsdos
Copy link
Member

nielsdos commented Mar 7, 2025

I've looked into this and have worked on a patch to get rid of the RC hacks and properly implementing delayed separation. The nice bonus is that we now get rid of some TODOs and that the issue fixed by this PR is fixed "automatically".
The downside is that this (obviously) breaks the "fixes" done in #10749.

However, besides the fact that PR #10749 can cause memory corruption due to the dangling Bucket pointer, I think the "bugs" it tried to fix were never bugs to begin with. (You can also see that an existing test case changed behaviour).
SPL returns a new iterator object for the same array, not via reference (the constructor does not take references), but as a proper array zval. Note that this means we have a refcount of 2 for the array. Since arrays are CoW it's expected that only the child array is modified and the parent is kept alone. So this all followed the classic PHP behaviour prior to the PR. However, after the PR we do modify the array and not even via references, so this breaks the standard PHP semantics.
In fact, there's a user note from 11 years ago that explains this behaviour on https://www.php.net/manual/en/recursivearrayiterator.getchildren.php
So I think the "fixes" should be reverted, and array separation should be done delayed. And those 2 changes should go to master.

@iluuu1994
Copy link
Member Author

@nielsdos Thank you! I would also prefer proper separation over eager cloning from this PR, so let me close it.

@iluuu1994 iluuu1994 closed this Mar 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants