[librsvg/librsvg-2.44] (#497): Don't panic on paths with all-invalid commands



commit 4ce5fa5518f43257568bb9b2f00899abe25c92c9
Author: Federico Mena Quintero <federico gnome org>
Date:   Sat Aug 17 15:09:01 2019 -0500

    (#497): Don't panic on paths with all-invalid commands
    
    The path parser creates a PathBuilder with zero commands.
    
    In turn, builder.to_cairo() does nothing, as expected.
    
    But then we stroke_and_fill(), and the wrapper call to
    with_discrete_layer() doesn't like not having bounds.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/497

 rsvg_internals/src/path_builder.rs                 |  6 ++++
 rsvg_internals/src/shapes.rs                       | 32 ++++++++++++----------
 .../497-path-with-all-invalid-commands.svg         | 13 +++++++++
 3 files changed, 36 insertions(+), 15 deletions(-)
---
diff --git a/rsvg_internals/src/path_builder.rs b/rsvg_internals/src/path_builder.rs
index 2de523dd..90e48429 100644
--- a/rsvg_internals/src/path_builder.rs
+++ b/rsvg_internals/src/path_builder.rs
@@ -356,6 +356,8 @@ impl PathBuilder {
     }
 
     pub fn to_cairo(&self, cr: &cairo::Context) -> Result<(), cairo::Status> {
+        assert!(!self.empty());
+
         for s in &self.path_commands {
             s.to_cairo(cr);
         }
@@ -376,6 +378,10 @@ impl PathBuilder {
             Err(status)
         }
     }
+
+    pub fn empty(&self) -> bool {
+        self.path_commands.len() == 0
+    }
 }
 
 #[cfg(test)]
diff --git a/rsvg_internals/src/shapes.rs b/rsvg_internals/src/shapes.rs
index cc19d69b..a44871a4 100644
--- a/rsvg_internals/src/shapes.rs
+++ b/rsvg_internals/src/shapes.rs
@@ -23,24 +23,26 @@ fn render_path_builder(
     render_markers: bool,
     clipping: bool,
 ) -> Result<(), RenderingError> {
-    draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
-        let cr = dc.get_cairo_context();
+    if !builder.empty() {
+        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
+            let cr = dc.get_cairo_context();
+
+            dc.set_affine_on_cr(&cr);
+            builder.to_cairo(&cr)?;
+
+            if clipping {
+                cr.set_fill_rule(cairo::FillRule::from(values.clip_rule));
+            } else {
+                cr.set_fill_rule(cairo::FillRule::from(values.fill_rule));
+                dc.stroke_and_fill(&cr, values)?;
+            }
 
-        dc.set_affine_on_cr(&cr);
-        builder.to_cairo(&cr)?;
+            Ok(())
+        })?;
 
-        if clipping {
-            cr.set_fill_rule(cairo::FillRule::from(values.clip_rule));
-        } else {
-            cr.set_fill_rule(cairo::FillRule::from(values.fill_rule));
-            dc.stroke_and_fill(&cr, values)?;
+        if render_markers {
+            marker::render_markers_for_path_builder(builder, draw_ctx, values, clipping)?;
         }
-
-        Ok(())
-    })?;
-
-    if render_markers {
-        marker::render_markers_for_path_builder(builder, draw_ctx, values, clipping)?;
     }
 
     Ok(())
diff --git a/tests/fixtures/render-crash/497-path-with-all-invalid-commands.svg 
b/tests/fixtures/render-crash/497-path-with-all-invalid-commands.svg
new file mode 100644
index 00000000..4aaf4c8f
--- /dev/null
+++ b/tests/fixtures/render-crash/497-path-with-all-invalid-commands.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="hg" width="100" height="100">
+  <defs>
+    <clipPath id="one" clipPathUnits="objectBoundingBox">
+  <path d="M 0P5 0.0 L 1.0 0.5 L 0.5 1.0 L 0.0 0.5 Z"/>
+</clipPath>
+  </defs>
+  <g clip-path="url(#one)">
+
+  <path d="M 0P5 " wiGth="40" height="40" fill="blue"/>
+    <rect x="50" y="50" width="40" heiKht="40" fill="#00ff00"/>
+  </g>
+</svg>


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