From a18c6e2c78b5958948dc9775e2c81e631e487911 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 7 May 2025 00:35:26 -0400 Subject: [PATCH] Fix double borrow panic in Node.childNodes (#36889) `ensure_rare_data` returns a RefMut that extends the borrow of Node.rare_data. This can lead to a panic in any method that triggers a GC while this borrow is outstanding, such as Node.childNodes. Testing: Manual testing on the testcase from the issue. It is impossible to create a deterministic WPT crash test that is fast enough and can be counted upon to continue working in the future. Fixes: #36868 Signed-off-by: Josh Matthews --- components/script/dom/node.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index e9d36a01426..ca785773b48 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -3110,11 +3110,15 @@ impl NodeMethods for Node { /// fn ChildNodes(&self, can_gc: CanGc) -> DomRoot { - self.ensure_rare_data().child_list.or_init(|| { - let doc = self.owner_doc(); - let window = doc.window(); - NodeList::new_child_list(window, self, can_gc) - }) + if let Some(list) = self.ensure_rare_data().child_list.get() { + return list; + } + + let doc = self.owner_doc(); + let window = doc.window(); + let list = NodeList::new_child_list(window, self, can_gc); + self.ensure_rare_data().child_list.set(Some(&list)); + list } ///