-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Prevent infinite loop in revealing algorithms #11457
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
Conversation
The ancestor details revealing algorithm and the hidden until found revealing algorithm may both get stuck in infinite loops because they iterate the flat tree while firing synchronous events. If the page were to listen to these events and change the flat tree in response, then the algorithm could theoretically never end. Fixes whatwg#11436
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Editorially LGTM, although some implementer review from @nt1m and/or @jnjaeschke would be appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think going through every single ancestor twice is very unefficient. The second loop should only go through relevant elements, rather than all of the ancestors again. I know it may result in some behavior difference in some very specific edge cases, but I'd rather have an efficient algorithm here.
Yeah, this seems like the right time to combine these algorithms so we only do a single tree walk. That's an observable change in behavior due to the events, but I think it's very much an acceptable one. And if we ever add more cases we care about we don't end up with ever more ancestor walks. |
Just to be clear, I was pointing out that the current PR collects all the ancestors into a list for both algorithms, instead of only the relevant ones for each algorithm, which is different from what Anne mentioned in the previous comment. (But having 1 reveal algorithm instead of 2 separate ones as Anne suggests wouldn't be something I'm opposed to, if the change in order of events/revealing makes sense for web developers) |
@nt1m and I discussed this some more and while in theory you could do a single ancestor walk and collect the nodes to dispatch events on in separate lists depending on the feature, my suspicion is that it would be more useful for web developers if the events are also collapsed into a single reverse-tree-ordered list. |
Thanks, I combined the algorithms and only stored relevant nodes for the second traversal. How does it look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After we fire the first event, do we want to check for each node we go through that it's still connected?
And maybe check that the pre-conditions are still valid?
And maybe that if any of that is no longer true, we return early as we're no longer sure what we're dealing with.
I added checks to make sure that each ancestor to reveal is still connected and still has the open attribute if its a details or still has hidden=until-found otherwise, and stop the algorithm if any of those are not true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. Couple of nits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, modulo a couple of nits.
@jnjaeschke @nt1m do we already have bugs tracking this change for Gecko and WebKit? |
There's no Gecko bug that I know of. |
I filed a gecko bug and put it in the OP |
<li><p>If <var>ancestorToReveal</var> is not <span>connected</span>, then return.</p></li> | ||
|
||
<li><p>If <var>ancestorToReveal</var>'s <code data-x="attr-hidden">hidden</code> attribute is | ||
not in the <span data-x="attr-hidden-until-found-state">Hidden Until Found</span> state, then | ||
return.</p></li> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm currently discussing this with @annevk but I'm not convinced these checks are good for component based websites. The fact that child components can break parent components behaviors seems pretty unexpected to me. E.g. a parent component that is expecting revealing behavior on find-in-page should not have that be unintentionally prevented by a child component getting removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR can be merged as is for now, I'll raise a follow up issue if needed.
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details.html: Added. * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 Also write a bunch of new WPT for ordering & state mutations during the beforematch event. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-infinite-loop-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details.html: Added. * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 which: - Prevents infinite looping due to mutations on the beforematch event, by collecting the ancestors beforehand (covered by beforematch-infinite-loop.html) - Combines both details and hidden=until-found ancestor revealing algorithms into a single one, to avoid two separate traversals (covered by hidden-until-found-and-details.html) - Adds checks for attribute/element removal mutations during the beforematch event (covered by removal WPTs) Also write WPTs for previously uncovered parts. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-infinite-loop-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details.html: Added. * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
@josepharhar @jnjaeschke I wrote a bunch of WPTs here: web-platform-tests/wpt#54116 |
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 which: - Prevents infinite looping due to mutations on the beforematch event, by collecting the ancestors beforehand (covered by beforematch-infinite-loop.html) - Combines both details and hidden=until-found ancestor revealing algorithms into a single one, to avoid two separate traversals (covered by hidden-until-found-and-details.html) - Adds checks for attribute/element removal mutations during the beforematch event (covered by removal WPTs) Also write WPTs for previously uncovered parts. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-infinite-loop-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details.html: Added. * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by NOBODY (OOPS!). Follow whatwg/html#11457 which: - Prevents infinite looping due to mutations on the beforematch event, by collecting the ancestors beforehand (covered by beforematch-infinite-loop.html) - Combines both details and hidden=until-found ancestor revealing algorithms into a single one, to avoid two separate traversals (covered by hidden-until-found-and-details.html) - Adds checks for attribute/element removal mutations during the beforematch event (covered by removal WPTs) Also write WPTs for previously uncovered parts. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-infinite-loop-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details.html: Added. * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h:
https://bugs.webkit.org/show_bug.cgi?id=296797 rdar://157280008 Reviewed by Darin Adler. Follow whatwg/html#11457 which: - Prevents infinite looping due to mutations on the beforematch event, by collecting the ancestors beforehand (covered by beforematch-infinite-loop.html) - Combines both details and hidden=until-found ancestor revealing algorithms into a single one, to avoid two separate traversals (covered by hidden-until-found-and-details.html) - Adds checks for attribute/element removal mutations during the beforematch event (covered by removal WPTs) Also write WPTs for previously uncovered parts. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-attribute-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-001.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-element-removal-002.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/beforematch-infinite-loop-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/editing/the-hidden-attribute/hidden-until-found-and-details.html: Added. * Source/WebCore/dom/FindRevealAlgorithms.cpp: (WebCore::revealClosedDetailsAndHiddenUntilFoundAncestors): (WebCore::revealClosedDetailsAncestors): Deleted. (WebCore::revealHiddenUntilFoundAncestors): Deleted. * Source/WebCore/dom/FindRevealAlgorithms.h: Canonical link: https://commits.webkit.org/298164@main
This patch implements the spec changes for the auto-expanding algorithms for details elements and hidden=until-found: whatwg/html#11457 I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/SeRScSVsUXY Fixed: 433545121 Change-Id: I09d58f2c1b97c98c33d9c577369cb877198404c5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6821516 Reviewed-by: Mason Freed <[email protected]> Commit-Queue: Joey Arhar <[email protected]> Cr-Commit-Position: refs/heads/main@{#1500237}
The ancestor details revealing algorithm and the hidden until found revealing algorithm may both get stuck in infinite loops because they iterate the flat tree while firing synchronous events. If the page were to listen to these events and change the flat tree in response, then the algorithm could theoretically never end.
Fixes #11436
(See WHATWG Working Mode: Changes for more details.)
/browsing-the-web.html ( diff )
/interaction.html ( diff )
/interactive-elements.html ( diff )