xlib-xcb: Fix some use-after-free

Also, this now sets surface->xcb to NULL after the dereference. Segfaults are
way more prominent anyway. :-)

All the backend callbacks shouldn't need any checks since the public entry point
already checks for finished surfaces. Only the public functions in xlib-xcb need
to do checks for finished surfaces.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2011-07-02 23:00:24 +02:00
parent 880566e14b
commit 9e4c73a40d

View file

@ -80,6 +80,7 @@ _cairo_xlib_xcb_surface_finish (void *abstract_surface)
cairo_surface_finish (&surface->xcb->base);
status = surface->xcb->base.status;
cairo_surface_destroy (&surface->xcb->base);
surface->xcb = NULL;
return status;
}
@ -483,6 +484,10 @@ cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
{
cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface;
if (unlikely (abstract_surface->finished)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED);
return 0;
}
if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
@ -528,6 +533,10 @@ cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
{
cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface;
if (unlikely (abstract_surface->finished)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED);
return 0;
}
if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
@ -547,6 +556,10 @@ cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface)
{
cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface;
if (unlikely (abstract_surface->finished)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED);
return 0;
}
if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
@ -566,6 +579,10 @@ cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface)
{
cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface;
if (unlikely (abstract_surface->finished)) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED);
return 0;
}
if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;