[librsvg/librsvg-2.42] (#276) - Guard against getting a cairo_t in an error state at the toplevel API
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.42] (#276) - Guard against getting a cairo_t in an error state at the toplevel API
- Date: Fri, 1 Jun 2018 15:03:30 +0000 (UTC)
commit b99692db46e2a6c61d37a70165198ad029c4ec69
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Jun 1 09:59:24 2018 -0500
(#276) - Guard against getting a cairo_t in an error state at the toplevel API
The cairo-dock program was passing a cairo_t in an error state to
rsvg_handle_render_cairo(), and so we failed deep in the innards of
librsvg when cairo-rs validates the cairo::Context's status.
Cairo-dock was doing something like
surf = cairo_image_surface_create (... an invalid size ...);
cr = cairo_create (surf);
rsvg_handle_render_cairo (handle, cr); // we now catch the error right here
We catch invalid cr's, emit a warning, and return FALSE from
rsvg_handle_render_cairo*().
https://gitlab.gnome.org/GNOME/librsvg/issues/276
librsvg/rsvg-cairo-render.c | 11 +++++++++++
tests/api.c | 27 +++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
---
diff --git a/librsvg/rsvg-cairo-render.c b/librsvg/rsvg-cairo-render.c
index 112d59f9..c8c66efc 100644
--- a/librsvg/rsvg-cairo-render.c
+++ b/librsvg/rsvg-cairo-render.c
@@ -224,16 +224,27 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
{
RsvgDrawingCtx *draw;
RsvgNode *drawsub = NULL;
+ cairo_status_t status;
g_return_val_if_fail (handle != NULL, FALSE);
if (handle->priv->state != RSVG_HANDLE_STATE_CLOSED_OK)
return FALSE;
+ status = cairo_status (cr);
+
+ if (status != CAIRO_STATUS_SUCCESS) {
+ g_warning ("cannot render on a cairo_t with a failure status (status=%d, %s)",
+ (int) status,
+ cairo_status_to_string (status));
+ return FALSE;
+ }
+
if (id && *id)
drawsub = rsvg_defs_lookup (handle->priv->defs, id);
if (drawsub == NULL && id != NULL) {
+ g_warning ("element id=\"%s\" does not exist", id);
/* todo: there's no way to signal that @id doesn't exist */
return FALSE;
}
diff --git a/tests/api.c b/tests/api.c
index 018cdee8..75b5d7af 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -465,6 +465,32 @@ dimensions_and_position (void)
g_object_unref (handle);
}
+static void
+detects_cairo_context_in_error (void)
+{
+ if (g_test_subprocess ()) {
+ char *filename = get_test_filename ("example.svg");
+ GError *error = NULL;
+
+ RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+ g_assert (handle != NULL);
+ g_assert (error == NULL);
+
+ /* this is wrong; it is to simulate creating a surface and a cairo_t in error */
+ cairo_surface_t *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, -1, -1);
+ cairo_t *cr = cairo_create (surf);
+
+ /* rsvg_handle_render_cairo() should return FALSE when it gets a cr in an error state */
+ g_assert (!rsvg_handle_render_cairo (handle, cr));
+
+ return;
+ }
+
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*WARNING*cannot render on a cairo_t with a failure status*");
+}
+
int
main (int argc, char **argv)
{
@@ -491,6 +517,7 @@ main (int argc, char **argv)
g_test_add_func ("/api/handle_get_pixbuf", handle_get_pixbuf);
g_test_add_func ("/api/handle_get_pixbuf_sub", handle_get_pixbuf_sub);
g_test_add_func ("/api/dimensions_and_position", dimensions_and_position);
+ g_test_add_func ("/api/detects_cairo_context_in_error", detects_cairo_context_in_error);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]