[librsvg: 1/2] Do not assert if we ask dimensions of a file with no ink box



commit b4ab2aaacbc711a2f8a7a896b9035acb99c6fd97
Author: Paolo Borelli <pborelli gnome org>
Date:   Mon Aug 27 15:23:36 2018 +0200

    Do not assert if we ask dimensions of a file with no ink box
    
    Avoid to assert on files that do not have ink box at all.
    Also add a testcase and improve the test.
    Hopefully fixes https://gitlab.gnome.org/GNOME/librsvg/issues/324:
    at least it fixes the mininal test case, but the crash of vmware
    viewer needs to be tested.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/324

 librsvg/rsvg-handle.c                         |  8 ++++---
 librsvg/rsvg-private.h                        |  2 +-
 rsvg_internals/src/drawing_ctx.rs             | 21 +++++++++++-------
 tests/fixtures/render-crash/324-empty-svg.svg |  2 ++
 tests/render-crash.c                          | 31 ++++++++++++++++++---------
 5 files changed, 42 insertions(+), 22 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index f7ab66e5..fe14a564 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -1124,13 +1124,13 @@ get_node_ink_rect(RsvgHandle *handle, RsvgNode *node, cairo_rectangle_t *ink_rec
     cairo_surface_t *target;
     cairo_t *cr;
     RsvgDrawingCtx *draw;
-    gboolean res;
+    gboolean res = FALSE;
 
     g_assert (node != NULL);
 
     rsvg_handle_get_dimensions (handle, &dimensions);
     if (dimensions.width == 0 || dimensions.height == 0)
-        return FALSE;
+        return res;
 
     target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
     cr = cairo_create (target);
@@ -1140,7 +1140,9 @@ get_node_ink_rect(RsvgHandle *handle, RsvgNode *node, cairo_rectangle_t *ink_rec
 
     rsvg_tree_cascade (handle->priv->tree);
     res = rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->tree);
-    rsvg_drawing_ctx_get_ink_rect (draw, ink_rect);
+    if (res) {
+        res = rsvg_drawing_ctx_get_ink_rect (draw, ink_rect);
+    }
 
     rsvg_drawing_ctx_free (draw);
     cairo_destroy (cr);
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index b9b110cb..4e681a0e 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -262,7 +262,7 @@ gboolean rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx, RsvgTree *t
 
 /* Defined in rsvg_internals/src/drawing_ctx.rs */
 G_GNUC_INTERNAL
-void rsvg_drawing_ctx_get_ink_rect (RsvgDrawingCtx *ctx, cairo_rectangle_t *ink_rect);
+gboolean rsvg_drawing_ctx_get_ink_rect (RsvgDrawingCtx *ctx, cairo_rectangle_t *ink_rect);
 
 /* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 1eec002d..556d1804 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -1006,19 +1006,24 @@ pub extern "C" fn rsvg_drawing_ctx_add_node_and_ancestors_to_stack(
 pub extern "C" fn rsvg_drawing_ctx_get_ink_rect(
     raw_draw_ctx: *const RsvgDrawingCtx,
     ink_rect: *mut cairo_sys::cairo_rectangle_t,
-) {
+) -> glib_sys::gboolean {
     assert!(!raw_draw_ctx.is_null());
     let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx) };
 
     assert!(!ink_rect.is_null());
 
-    let r = draw_ctx.get_bbox().ink_rect.unwrap();
-    unsafe {
-        (*ink_rect).x = r.x;
-        (*ink_rect).y = r.y;
-        (*ink_rect).width = r.width;
-        (*ink_rect).height = r.height;
-    }
+    let res = match draw_ctx.get_bbox().ink_rect {
+        Some(r) => unsafe {
+            (*ink_rect).x = r.x;
+            (*ink_rect).y = r.y;
+            (*ink_rect).width = r.width;
+            (*ink_rect).height = r.height;
+            true
+        },
+        _ => false,
+    };
+
+    res.to_glib()
 }
 
 pub struct AcquiredNode(*const RefCell<Vec<RsvgNode>>, RsvgNode);
diff --git a/tests/fixtures/render-crash/324-empty-svg.svg b/tests/fixtures/render-crash/324-empty-svg.svg
new file mode 100644
index 00000000..e0af766e
--- /dev/null
+++ b/tests/fixtures/render-crash/324-empty-svg.svg
@@ -0,0 +1,2 @@
+<svg xmlns="http://www.w3.org/2000/svg";>
+</svg>
diff --git a/tests/render-crash.c b/tests/render-crash.c
index 04df7178..cf9c704e 100644
--- a/tests/render-crash.c
+++ b/tests/render-crash.c
@@ -18,16 +18,27 @@ test_render_crash (gconstpointer data)
     g_assert_no_error (error);
     g_assert (handle != NULL);
 
-    rsvg_handle_get_dimensions (handle, &dimensions);
-    g_assert (dimensions.width > 0);
-    g_assert (dimensions.height > 0);
-    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                         dimensions.width, dimensions.height);
-    cr = cairo_create (surface);
-    g_assert (rsvg_handle_render_cairo (handle, cr));
-
-    cairo_surface_destroy (surface);
-    cairo_destroy (cr);
+    /* rsvg_handle_get_dimensions_sub has a return value we can check */
+    if (rsvg_handle_get_dimensions_sub (handle, &dimensions, NULL)) {
+        RsvgDimensionData dimensions2;
+
+        g_assert_cmpint (dimensions.width, >, 0);
+        g_assert_cmpint (dimensions.height, >, 0);
+
+        rsvg_handle_get_dimensions (handle, &dimensions2);
+        g_assert_cmpint (dimensions2.width, ==, dimensions.width);
+        g_assert_cmpint (dimensions2.height, ==, dimensions.height);
+
+        surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dimensions.width, dimensions.height);
+        cr = cairo_create (surface);
+        g_assert (rsvg_handle_render_cairo (handle, cr));
+
+        cairo_surface_destroy (surface);
+        cairo_destroy (cr);
+    } else {
+        g_assert_cmpint (dimensions.width, ==, 0);
+        g_assert_cmpint (dimensions.height, ==, 0);
+    }
 
     g_object_unref (handle);
 }


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