diff options
author | Federico Mena Quintero <federico@gnome.org> | 2022-03-14 11:38:47 -0600 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2022-03-14 12:20:31 -0600 |
commit | b51a393216e49aff1ab780f75c136d6b61641ad5 (patch) | |
tree | 268008c39027ac0db313ad17080a10baf53b8512 /src/drawing_ctx.rs | |
parent | c5d0eb679ee45377417bbf9ce2dabde0eb72802d (diff) | |
download | librsvg-b51a393216e49aff1ab780f75c136d6b61641ad5.tar.gz |
(#721): Catch circular references when drawing patterns
It seems I broke this when splitting patterns into the resolve stage
and the drawing stage.
Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/721
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/679>
Diffstat (limited to 'src/drawing_ctx.rs')
-rw-r--r-- | src/drawing_ctx.rs | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs index 82071112..ead91b55 100644 --- a/src/drawing_ctx.rs +++ b/src/drawing_ctx.rs @@ -1035,10 +1035,25 @@ impl DrawingCtx { pattern: &UserSpacePattern, acquired_nodes: &mut AcquiredNodes<'_>, ) -> Result<bool, RenderingError> { + // Bail out early if the pattern has zero size, per the spec if approx_eq!(f64, pattern.width, 0.0) || approx_eq!(f64, pattern.height, 0.0) { return Ok(false); } + // Bail out early if this pattern has a circular reference + let pattern_node_acquired = match pattern.acquire_pattern_node(acquired_nodes) { + Ok(n) => n, + + Err(AcquireError::CircularReference(ref node)) => { + rsvg_log!("circular reference in element {}", node); + return Ok(false); + } + + _ => unreachable!(), + }; + + let pattern_node = pattern_node_acquired.get(); + let taffine = self.get_transform().pre_transform(&pattern.transform); let mut scwscale = (taffine.xx.powi(2) + taffine.xy.powi(2)).sqrt(); @@ -1084,11 +1099,10 @@ impl DrawingCtx { pattern_draw_ctx .with_alpha(pattern.opacity, &mut |dc| { - let pattern_cascaded = - CascadedValues::new_from_node(&pattern.node_with_children); + let pattern_cascaded = CascadedValues::new_from_node(pattern_node); let pattern_values = pattern_cascaded.get(); - let elt = pattern.node_with_children.borrow_element(); + let elt = pattern_node.borrow_element(); let stacking_ctx = StackingContext::new( acquired_nodes, @@ -1104,12 +1118,7 @@ impl DrawingCtx { false, None, &mut |an, dc, _transform| { - pattern.node_with_children.draw_children( - an, - &pattern_cascaded, - dc, - false, - ) + pattern_node.draw_children(an, &pattern_cascaded, dc, false) }, ) }) |