From 6da7f140334835be9a972db75de78d99b8bd24b1 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 2 Mar 2007 03:49:11 -0800 Subject: [PATCH] Fix INVALID_RESTORE case to avoid crashes Previously, an INVALID_RESTORE error would leave cr->gstate as NULL, (which is generally impossible/invalid). This seems safe enough as most cairo functions check cr->status first and bail if anything looks fishy. However, the many cairo_get functions happily march along in spite of any current error. We could instrument all of those functions to check for the error status and return some dummy value in that case. But it's much easier to get the same basic effect by simply creating a non-NULL cr->gstate which will hold all those dummy values, and we can eliminate the crashes without having to touch up every cairo_get function. This fixes the bug reported here: evolution crash to _cairo_gstate_backend_to_user() https://bugs.freedesktop.org/show_bug.cgi?id=9906 It also eliminates the crash that was added to the nil-surface test with the previous commit. --- src/cairo.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cairo.c b/src/cairo.c index b487baba7..fb799e1e1 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -408,8 +408,16 @@ cairo_restore (cairo_t *cr) _cairo_gstate_destroy (top); - if (cr->gstate == NULL) + if (cr->gstate == NULL) { _cairo_set_error (cr, CAIRO_STATUS_INVALID_RESTORE); + /* We go ahead and create a new gstate here, just for the sake + * of the various cairo_get functions that don't check + * cr->status. This gstate should never be written to, (since + * the cairo functions that do modify anything all check + * status and immediately abort). + */ + cr->gstate = _cairo_gstate_create ((cairo_surface_t *)&_cairo_surface_nil); + } } slim_hidden_def(cairo_restore);