Assert that style element has an owner in parse_own_css (#39458)

The existing `assert!(node.is_connected())` is wrong. What it *wants* to
assert is that the style element has an owner, which is either a
Document or a ShadowRoot that the element is a descendant of. However,
if the element is descendant of a ShadowRoot which is itself not
connected to a document then the assertion would fail.

Instead, we use `node.is_in_a_document_tree() ||
node.is_in_a_shadow_tree()`, which more accurately reflects the intent.

Testing: This change adds the test case from
https://github.com/servo/servo/issues/37781 as a crashtest
Fixes https://github.com/servo/servo/issues/39457
Fixes https://github.com/servo/servo/issues/37781

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-09-24 01:00:11 +02:00 committed by GitHub
parent dd8e4f231c
commit 206dcff080
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 1 deletions

View file

@ -97,7 +97,10 @@ impl HTMLStyleElement {
pub(crate) fn parse_own_css(&self) {
let node = self.upcast::<Node>();
assert!(node.is_connected());
assert!(
node.is_in_a_document_tree() || node.is_in_a_shadow_tree(),
"This stylesheet does not have an owner, so there's no reason to parse its contents"
);
// Step 4. of <https://html.spec.whatwg.org/multipage/#the-style-element%3Aupdate-a-style-block>
let mut type_attribute = self.Type();

View file

@ -10380,6 +10380,13 @@
{}
]
],
"modify-style-element-in-disconnected-shadow-crash.html": [
"3808642a97451eef40573214fbe1d1c6273c557f",
[
null,
{}
]
],
"move-to-new-tree-1343016.html": [
"853884b99301e22383e0fd0936cf154beab5e93e",
[

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Modifying a style element in a disconnected shadow tree should not crash</title>
<link rel="help" href="https://github.com/servo/servo/issues/37781">
</head>
<body>
<script>
let d = document.createElement('div');
let s = d.attachShadow({mode: "open"});
let s2 = document.createElement('style');
s.appendChild(s2);
s2.textContent = "lol";
</script>
</body>
</html>