Skip to content

Fix GH-11288 and GH-11289 and GH-11290 and GH-9142: DOMExceptions and segfaults with replaceWith #11299

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 3 commits into from

Conversation

nielsdos
Copy link
Member

This replaces the implementation of before and after with one following the spec very strictly, instead of trying to figure out the state we're in by looking at the pointers. Also relaxes the condition on text node copying to prevent working on a stale node pointer.

…ception with replaceWith

This replaces the implementation of before and after with one following
the spec very strictly, instead of trying to figure out the state we're
in by looking at the pointers. Also relaxes the condition on text node
copying to prevent working on a stale node pointer.
@nielsdos nielsdos changed the title Fix GH-11288 and GH-11289: DOMException with replaceWith Fix GH-11288 and GH-11289 and GH-11290 and GH-9142: DOMException with replaceWith May 22, 2023
@nielsdos
Copy link
Member Author

nielsdos commented May 22, 2023

Ugh Travis fails because the output formatting of saveHTML is different: some newlines are added in the output and some not, but the result is correct... I'll do a postprocess step that just strips newlines I guess :/

EDIT: pushed a commit to fix output formatting due to different libxml versions, hopefully this fixes it otherwise I'll take a look again.

@nielsdos nielsdos changed the title Fix GH-11288 and GH-11289 and GH-11290 and GH-9142: DOMException with replaceWith Fix GH-11288 and GH-11289 and GH-11290 and GH-9142: DOMExceptions and segfaults with replaceWith May 23, 2023
Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks sensible cross checking with the spec. I'm just confused by one thing.

Thank you for tackling this!

parentNode = nextsib->parent;
beforefirstchild = !prevsib;

/* Spec step 2 appears to be handled by dom_zvals_to_fragment */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused why this is handled explicitly in the after version but not in the before one. Would be better to be consistent in both functions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I thought it was fine first because of the document check in dom_zvals_to_fragment. Then I realised it was not and only commented the after version and forgot about this one.
In fact, I believe both before&after should throw HIERARCHY_REQUEST_ERR instead of NO_MODIFICATION_ALLOWED: this is because not having a parent is an invalid hierarchy while NO_MODIFICATION_ALLOWED is used for attempting to modify read-only stuff.
I changed both before and after to throw HIERARCHY_REQUEST_ERR if spec step 2 fails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense for the HIERARCHY_REQUEST_ERR 👍

@@ -0,0 +1,20 @@
--TEST--
GH-9142 (DOMChildNode replaceWith() double-free error when replacing elements not separated by any whitespace)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused as to how replaceWith is getting affected, as it seems only thebefore and after methods seem to have fixes. Is it because the replace method "call" the two others ones somehow?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaceWith calls after, and then remove.

php-src/ext/dom/element.c

Lines 1254 to 1255 in adb3d52

dom_parent_node_after(intern, args, argc);
dom_child_node_remove(intern);

So spec compliance problem caused problems with replaceWith as well, indirectly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhhhhh right, that makes snese then :)

@nielsdos nielsdos closed this in cba335d May 25, 2023
@nielsdos
Copy link
Member Author

Thanks for the review, George.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants