[PATCH] fix a crash caused by finished SVG surface

Kouhei Sutou <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Hi,

I attach a patch that fix a crash that is caused by finished
SVG surface. "cairo_create (finished_svg_surface)" is invalid
usage but it will be better that reporting an error instead
of crash.

Here is a program that reproduces this case:

#include <cairo.h>
#include <cairo-svg.h>

int
main(int argc, char **argv)
{
  cairo_t *cr;
  cairo_surface_t *finished_surface;

  finished_surface = cairo_svg_surface_create ("/tmp/xxx.svg", 1.0, 1.0);
  cairo_surface_finish (finished_surface);

  cr = cairo_create (finished_surface);
  cairo_destroy (cr);

  cairo_surface_destroy (finished_surface);

  return 0;
}

We can use other paginated surface such as PDF surface for
finished surface.


This case is reported at rcairo's issue:
https://github.com/rcairo/rcairo/issues/15


Thanks,
--
kou

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
0001-cairo_create-Add-finished-surface-check.patch (text/x-patch, 1.3 KB)
From 4ea48e8da696b7e4063e330398c59947564fea5b Mon Sep 17 00:00:00 2001
From: Kouhei Sutou <[email protected]>
Date: Mon, 28 Oct 2013 22:37:54 +0900
Subject: [PATCH] cairo_create(): Add finished surface check

Without this change, the following program crashes:

    #include <cairo.h>
    #include <cairo-svg.h>

    int
    main(int argc, char **argv)
    {
      cairo_t *cr;
      cairo_surface_t *finished_surface;

      finished_surface = cairo_svg_surface_create ("/tmp/xxx.svg", 1.0, 1.0);
      cairo_surface_finish (finished_surface);

      cr = cairo_create (finished_surface);
      cairo_destroy (cr);

      cairo_surface_destroy (finished_surface);

      return 0;
    }
---
 src/cairo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/cairo.c b/src/cairo.c
index c7128ae..e3acf4d 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -230,6 +230,8 @@ cairo_create (cairo_surface_t *target)
 	return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
     if (unlikely (target->status))
 	return _cairo_create_in_error (target->status);
+    if (unlikely (target->finished))
+	return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
 
     if (target->backend->create_context == NULL)
 	return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR));
-- 
1.8.4.rc3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.