[librsvg] pattern: error out in case of reference loop



commit 8634059c20636fd3a848ae5cb4544f7524b3c1e6
Author: Paolo Borelli <pborelli gnome org>
Date:   Tue Jan 1 10:38:21 2019 +0100

    pattern: error out in case of reference loop
    
    This changes behavior, we used to ignore the loop and use the
    default. However both Firefox and Chrome error out in this case
    so let's return a rendering error.

 rsvg_internals/src/gradient.rs     | 6 +++---
 rsvg_internals/src/paint_server.rs | 4 ++--
 rsvg_internals/src/pattern.rs      | 8 +++-----
 tests/infinite-loop.c              | 2 +-
 4 files changed, 9 insertions(+), 11 deletions(-)
---
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index 3e02b89a..fb27d524 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -537,7 +537,7 @@ impl PaintSource for NodeGradient {
         node: &RsvgNode,
         draw_ctx: &mut DrawingCtx,
         bbox: &BoundingBox,
-    ) -> Option<Self::Source> {
+    ) -> Result<Option<Self::Source>, RenderingError> {
         let gradient =
             node.with_impl(|i: &NodeGradient| i.get_gradient_with_color_stops_from_node(node));
         let mut result = gradient.clone();
@@ -565,9 +565,9 @@ impl PaintSource for NodeGradient {
         }
 
         if result.bounds_are_valid(bbox) {
-            Some(result)
+            Ok(Some(result))
         } else {
-            None
+            Ok(None)
         }
     }
 
diff --git a/rsvg_internals/src/paint_server.rs b/rsvg_internals/src/paint_server.rs
index ce6750cb..48c4183a 100644
--- a/rsvg_internals/src/paint_server.rs
+++ b/rsvg_internals/src/paint_server.rs
@@ -57,7 +57,7 @@ pub trait PaintSource {
         node: &RsvgNode,
         draw_ctx: &mut DrawingCtx,
         bbox: &BoundingBox,
-    ) -> Option<Self::Source>;
+    ) -> Result<Option<Self::Source>, RenderingError>;
 
     fn set_pattern_on_draw_context(
         &self,
@@ -75,7 +75,7 @@ pub trait PaintSource {
         opacity: &UnitInterval,
         bbox: &BoundingBox,
     ) -> Result<bool, RenderingError> {
-        if let Some(resolved) = self.resolve(&node, draw_ctx, bbox) {
+        if let Some(resolved) = self.resolve(&node, draw_ctx, bbox)? {
             let cascaded = node.get_cascaded_values();
             let values = cascaded.get();
             self.set_pattern_on_draw_context(&resolved, values, draw_ctx, opacity, bbox)
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 0badb435..fa681e94 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -241,7 +241,7 @@ impl PaintSource for NodePattern {
         node: &RsvgNode,
         draw_ctx: &mut DrawingCtx,
         _bbox: &BoundingBox,
-    ) -> Option<Self::Source> {
+    ) -> Result<Option<Self::Source>, RenderingError> {
         let node_pattern = node.get_impl::<NodePattern>().unwrap();
         let pattern = &*node_pattern.pattern.borrow();
         let mut result = pattern.clone();
@@ -254,11 +254,9 @@ impl PaintSource for NodePattern {
                 let node = acquired.get();
 
                 if stack.contains(node) {
-                    // FIXME: return a Result here with RenderingError::CircularReference
                     // FIXME: print the pattern's name
                     rsvg_log!("circular reference in pattern");
-                    result.resolve_from_defaults();
-                    break;
+                    return Err(RenderingError::CircularReference);
                 }
 
                 node.with_impl(|i: &NodePattern| {
@@ -271,7 +269,7 @@ impl PaintSource for NodePattern {
             }
         }
 
-        Some(result)
+        Ok(Some(result))
     }
 
     fn set_pattern_on_draw_context(
diff --git a/tests/infinite-loop.c b/tests/infinite-loop.c
index 9eb7f394..459219f5 100644
--- a/tests/infinite-loop.c
+++ b/tests/infinite-loop.c
@@ -21,7 +21,7 @@ test_infinite_loop (gconstpointer data)
 
         surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
         cr = cairo_create (surface);
-        g_assert (rsvg_handle_render_cairo (handle, cr));
+        g_assert (!rsvg_handle_render_cairo (handle, cr));
 
         cairo_surface_destroy (surface);
         cairo_destroy (cr);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]