[librsvg/librsvg-2.40] 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/librsvg-2.40] bgo#621088: rsvg_cairo_clip_render_new(): Don't leave uninitialized fields in the parent RsvgCairoRe
- Date: Fri, 1 Sep 2017 15:01:57 +0000 (UTC)
commit 66c0f991db5ffe3e20f8d30c629d1c71148c746f
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 | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/rsvg-cairo-clip.c b/rsvg-cairo-clip.c
index f2af3e5..334c9d3 100644
--- a/rsvg-cairo-clip.c
+++ b/rsvg-cairo-clip.c
@@ -112,7 +112,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;
@@ -124,14 +124,23 @@ 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 = rsvg_cairo_clip_render_path;
+ 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;
+
clip_render->parent = parent;
return render;
@@ -140,10 +149,14 @@ rsvg_cairo_clip_render_new (cairo_t * cr, RsvgCairoRender *parent)
void
rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgClipPath * clip, RsvgBbox * bbox)
{
+ RsvgCairoClipRender *clip_render;
RsvgCairoRender *save = RSVG_CAIRO_RENDER (ctx->render);
+ cairo_t *cr;
cairo_matrix_t affinesave;
- 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;
/* Horribly dirty hack to have the bbox premultiplied to everything */
if (clip->units == objectBoundingBox) {
@@ -166,7 +179,11 @@ rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgClipPath * clip, RsvgBbox * bbox)
if (clip->units == objectBoundingBox)
clip->super.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]