LibWeb: Avoid a crash in Selection.containsNode() with a detached range
Problem: Selection.containsNode() crashes when the selection’s range has boundary points in a tree that’s not connected — such as a shadow tree whose host was removed. We also call that function internally for content-visibility:auto elements during rendering — so it can cause a page to crash even when the page itself doesn’t use the Selection API. Cause: When a shadow host is removed, a selection range whose boundary points are inside its shadow tree isn’t adjusted: live-range adjustment matches ranges by regular-tree descendant and doesn’t reach into shadow trees. The range is left pointing into the detached shadow tree. contains_node() verifies only the passed node against the document — not the range — then runs a boundary-point comparison that requires both sides to share a shadow-including root. Fix: Make contains_node() also confirm the range’s boundary points are rooted at the document. If not, then return false — because a node can’t be contained in a selection whose range is in a different tree. Fixes https://github.com/LadybirdBrowser/ladybird/issues/9469
This commit is contained in:
parent
2153535057
commit
4696a1ed97
2 changed files with 18 additions and 0 deletions
|
|
@ -482,6 +482,10 @@ bool Selection::contains_node(GC::Ref<DOM::Node> node, bool allow_partial_contai
|
|||
// The method must return false if this is empty or if node's root is not the document associated with this.
|
||||
if (!m_range)
|
||||
return false;
|
||||
// The range's boundary points can be in a tree that's not connected to the document (for example, inside the shadow
|
||||
// tree of a removed host). Such a range isn't comparable with a node in the document.
|
||||
if (&m_range->start().node->shadow_including_root() != m_document.ptr())
|
||||
return false;
|
||||
if (&node->root() != m_document.ptr())
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Regression test for https://github.com/LadybirdBrowser/ladybird/issues/9469
|
||||
Removing a shadow host leaves a selection range inside its shadow tree disconnected
|
||||
from the document. Selection.containsNode() must not crash on such a range. -->
|
||||
<div id="host"></div>
|
||||
<script>
|
||||
const host = document.getElementById("host");
|
||||
const shadow = host.attachShadow({ mode: "open" });
|
||||
shadow.innerHTML = "<span>shadow text</span>";
|
||||
const text = shadow.querySelector("span").firstChild;
|
||||
getSelection().setBaseAndExtent(text, 0, text, 4);
|
||||
host.remove();
|
||||
getSelection().containsNode(document.body, true);
|
||||
</script>
|
||||
Loading…
Reference in a new issue