summaryrefslogtreecommitdiff
path: root/src/drawing_ctx.rs
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2022-03-14 11:38:47 -0600
committerFederico Mena Quintero <federico@gnome.org>2022-03-14 12:20:31 -0600
commitb51a393216e49aff1ab780f75c136d6b61641ad5 (patch)
tree268008c39027ac0db313ad17080a10baf53b8512 /src/drawing_ctx.rs
parentc5d0eb679ee45377417bbf9ce2dabde0eb72802d (diff)
downloadlibrsvg-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.rs27
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)
},
)
})