[librsvg] bgo#621088: rsvg_cairo_clip_render_new(): Don't leave uninitialized fields in the parent RsvgCairoRe
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] bgo#621088: rsvg_cairo_clip_render_new(): Don't leave uninitialized fields in the parent RsvgCairoRe
- Date: Fri, 1 Sep 2017 14:47:23 +0000 (UTC)
commit 589e2dcf53bd05213bb17ed48e24d3f166e4fc92
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Sep 1 08:45:31 2017 -0500
bgo#621088: rsvg_cairo_clip_render_new(): Don't leave uninitialized fields in the parent RsvgCairoRender
A text object used as a clip path caused librsvg to crash. The reason
is that when we create an RsvgCairoClipRender, we were leaving an
all-zeros clip_render->super.bbox field.
This caused two things:
1. An all-zeros RsvgBbox is invalid; it should be "virgin" or actually
have a valid affine.
2. We were not preserving the bbox from the parent rendering context,
so the clipped objects would not know their viewport size. Now we
copy the original cairo_render->bbox to our derived
clip_render->super.bbox, and start afresh with an empty bb_stack
inside the clip_render.
rsvg-cairo-clip.c | 31 ++++++++++++++++++++++++++-----
1 files changed, 26 insertions(+), 5 deletions(-)
---
diff --git a/rsvg-cairo-clip.c b/rsvg-cairo-clip.c
index 8cb956b..5367285 100644
--- a/rsvg-cairo-clip.c
+++ b/rsvg-cairo-clip.c
@@ -115,7 +115,7 @@ rsvg_cairo_clip_add_clipping_rect (RsvgDrawingCtx * ctx, double x, double y, dou
}
static RsvgRender *
-rsvg_cairo_clip_render_new (cairo_t * cr, RsvgCairoRender *parent)
+rsvg_cairo_clip_render_new (cairo_t *cr, RsvgCairoRender *parent)
{
RsvgCairoClipRender *clip_render = g_new0 (RsvgCairoClipRender, 1);
RsvgCairoRender *cairo_render = &clip_render->super;
@@ -127,14 +127,27 @@ rsvg_cairo_clip_render_new (cairo_t * cr, RsvgCairoRender *parent)
render->free = rsvg_cairo_clip_render_free;
render->create_pango_context = rsvg_cairo_create_pango_context;
render->render_pango_layout = rsvg_cairo_render_pango_layout;
- render->render_surface = rsvg_cairo_clip_render_surface;
render->render_path_builder = rsvg_cairo_clip_render_path_builder;
+ render->render_surface = rsvg_cairo_clip_render_surface;
render->pop_discrete_layer = rsvg_cairo_clip_pop_discrete_layer;
render->push_discrete_layer = rsvg_cairo_clip_push_discrete_layer;
render->add_clipping_rect = rsvg_cairo_clip_add_clipping_rect;
render->get_surface_of_node = NULL;
+
cairo_render->initial_cr = parent->cr;
- cairo_render->cr = cr;
+ cairo_render->cr = cr;
+ cairo_render->width = parent->width;
+ cairo_render->height = parent->height;
+ cairo_render->offset_x = parent->offset_x;
+ cairo_render->offset_y = parent->offset_y;
+ cairo_render->cr_stack = NULL;
+ cairo_render->bbox = parent->bbox;
+ cairo_render->bb_stack = NULL;
+
+ /* We don't copy or ref the following two; we just share them */
+ cairo_render->font_config_for_testing = parent->font_config_for_testing;
+ cairo_render->font_map_for_testing = parent->font_map_for_testing;
+
clip_render->parent = parent;
return render;
@@ -144,14 +157,18 @@ void
rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgNode *node_clip_path, RsvgBbox * bbox)
{
RsvgClipPath *clip;
+ RsvgCairoClipRender *clip_render;
RsvgCairoRender *save = RSVG_CAIRO_RENDER (ctx->render);
cairo_matrix_t affinesave;
RsvgState *clip_path_state;
+ cairo_t *cr;
g_assert (rsvg_node_get_type (node_clip_path) == RSVG_NODE_TYPE_CLIP_PATH);
clip = rsvg_rust_cnode_get_impl (node_clip_path);
- ctx->render = rsvg_cairo_clip_render_new (save->cr, save);
+ cr = save->cr;
+ clip_render = RSVG_CAIRO_CLIP_RENDER (rsvg_cairo_clip_render_new (cr, save));
+ ctx->render = &clip_render->super.super;
clip_path_state = rsvg_node_get_state (node_clip_path);
@@ -176,7 +193,11 @@ rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgNode *node_clip_path, RsvgBbox * bbox
if (clip->units == objectBoundingBox)
clip_path_state->affine = affinesave;
+ g_assert (clip_render->super.cr_stack == NULL);
+ g_assert (clip_render->super.bb_stack == NULL);
+ g_assert (clip_render->super.surfaces_stack == NULL);
+
g_free (ctx->render);
- cairo_clip (save->cr);
+ cairo_clip (cr);
ctx->render = &save->super;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]