diff options
author | Uli Schlachter <psychon@znc.in> | 2011-07-02 23:00:24 +0200 |
---|---|---|
committer | Uli Schlachter <psychon@znc.in> | 2011-07-02 23:00:24 +0200 |
commit | 9e4c73a40d6eb72a5110936ab310acbaef99baa8 (patch) | |
tree | b965fe1f860bcd2fb646e4cbaf7233a3604c84bd | |
parent | 880566e14b335ddb5bf1c768f6ca4f02b2dd2add (diff) |
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>
-rw-r--r-- | src/cairo-xlib-xcb-surface.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c index 0462e037..07c27358 100644 --- a/src/cairo-xlib-xcb-surface.c +++ b/src/cairo-xlib-xcb-surface.c @@ -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; |