layout: Gracefully handle script queries on nodes with uninvertible transforms (#39075)

Instead of panicking when doing a geometry script query on a node with
an uninvertible transform, return a zero-sized rectangle at the
untransformed position. This is similar to what Gecko and Blink do
(though it seems there are some differences in positioning this
zero-sized rectangle). Mostly importantly, do not panic.

Testing: This change adds a new WPT crash test.
Fixes: #38848.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-09-02 06:27:43 -07:00 committed by GitHub
parent 4de84b0ca5
commit efe9ea2306
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 53 additions and 6 deletions

View file

@ -1009,6 +1009,7 @@ impl BoxFragment {
// > If a transform function causes the current transformation matrix of an object
// > to be non-invertible, the object and its content do not get displayed.
if !reference_frame_data.transform.is_invertible() {
self.clear_spatial_tree_node_including_descendants();
return;
}
@ -1705,6 +1706,29 @@ impl BoxFragment {
Perspective::None => None,
}
}
fn clear_spatial_tree_node_including_descendants(&self) {
fn assign_spatial_tree_node_on_fragments(fragments: &[Fragment]) {
for fragment in fragments.iter() {
match fragment {
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
box_fragment
.borrow()
.clear_spatial_tree_node_including_descendants();
},
Fragment::Positioning(positioning_fragment) => {
assign_spatial_tree_node_on_fragments(
&positioning_fragment.borrow().children,
);
},
_ => {},
}
}
}
*self.spatial_tree_node.borrow_mut() = None;
assign_spatial_tree_node_on_fragments(&self.children);
}
}
impl PositioningFragment {