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.
This commit is contained in:
Carl Worth 2007-03-02 03:49:11 -08:00
parent 36590fd470
commit 6da7f14033

View file

@ -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);