[cairo-commit] 4 commits - boilerplate/cairo-boilerplate-xlib.c src/cairo-xcb-surface-render.c src/cairo-xlib-xcb-surface.c

Uli Schlachter psychon at kemper.freedesktop.org
Sun Jul 3 06:17:29 PDT 2011


 boilerplate/cairo-boilerplate-xlib.c |    6 ++++
 src/cairo-xcb-surface-render.c       |   18 +++++-------
 src/cairo-xlib-xcb-surface.c         |   50 ++++++++++++++++++++++++-----------
 3 files changed, 49 insertions(+), 25 deletions(-)

New commits:
commit b6c972897b9d7cb898fb08363115e721a3ff758c
Author: Uli Schlachter <psychon at znc.in>
Date:   Sun Jul 3 13:13:37 2011 +0200

    Xlib: Fix boilerplate to work with xlib-xcb
    
    Xlib boilerplate includes cairo-xlib-surface-private.h, so that it can cast the
    xlib cairo_surface_t to cairo_xlib_surface_t and then mess with some internals
    of that struct.
    
    However, xlib-xcb doesn't use that struct and thus this results in random memory
    corruption. "Luckily", all the fields that this messes with don't corrupt any
    fields in cairo_xlib_xcb_surface_t, but instead this writes past the end of the
    buffer that was returned from malloc.
    
    This commit just adds an #if to disable this code section since I have no idea
    what a proper fix would be. This means that the xlib-fallback backend doesn't
    actually test any fallbacks with xlib-xcb, however it never did so anyway.
    
    If you have any idea how to fix xlib-fallback with xlib-xcb, please speak up.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index 797fe97..6818caf 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -412,6 +412,11 @@ _cairo_boilerplate_xlib_window_create_surface (const char		 *name,
 cairo_status_t
 cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface)
 {
+    /* The following stunt doesn't work with xlib-xcb because it doesn't use
+     * cairo_xlib_surface_t for its surfaces. Sadly, there is no sane
+     * alternative, so we can't disable render with xlib-xcb.
+     * FIXME: Find an alternative. */
+#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t*) abstract_surface;
 
     if (cairo_surface_get_type (abstract_surface) != CAIRO_SURFACE_TYPE_XLIB)
@@ -434,6 +439,7 @@ cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface
 #if CAIRO_XLIB_SURFACE_HAS_BUGGY_REPEAT
     surface->buggy_repeat = TRUE;
 #endif
+#endif
 
     return CAIRO_STATUS_SUCCESS;
 }
commit eea31cc4ee02f81554f04c3db60ab371c1cb212f
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Jul 2 23:11:48 2011 +0200

    xlib-xcb: Don't call directly into the xcb backend
    
    Instead, this now uses the surface wrapper functions for this job.
    These functions make sure that e.g. snapshots are detached and that is_clear is
    reset correctly.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 07c2735..8fe0e50 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -117,7 +117,7 @@ _cairo_xlib_xcb_surface_get_font_options (void *abstract_surface,
 					  cairo_font_options_t *options)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    surface->xcb->base.backend->get_font_options (surface->xcb, options);
+    cairo_surface_get_font_options (&surface->xcb->base, options);
 }
 
 static cairo_int_status_t
@@ -127,7 +127,7 @@ _cairo_xlib_xcb_surface_paint (void			*abstract_surface,
 			       cairo_clip_t		*clip)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return surface->xcb->base.backend->paint (surface->xcb, op, source, clip);
+    return _cairo_surface_paint (&surface->xcb->base, op, source, clip);
 }
 
 static cairo_int_status_t
@@ -138,7 +138,7 @@ _cairo_xlib_xcb_surface_mask (void			*abstract_surface,
 			      cairo_clip_t		*clip)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return surface->xcb->base.backend->mask (surface->xcb, op, source, mask, clip);
+    return _cairo_surface_mask (&surface->xcb->base, op, source, mask, clip);
 }
 
 static cairo_int_status_t
@@ -154,10 +154,9 @@ _cairo_xlib_xcb_surface_stroke (void				*abstract_surface,
 				cairo_clip_t			*clip)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return surface->xcb->base.backend->stroke (surface->xcb,
-					       op, source, path, style,
-					       ctm, ctm_inverse,
-					       tolerance, antialias, clip);
+    return _cairo_surface_stroke (&surface->xcb->base,
+				  op, source, path, style, ctm, ctm_inverse,
+				  tolerance, antialias, clip);
 }
 
 static cairo_int_status_t
@@ -171,10 +170,10 @@ _cairo_xlib_xcb_surface_fill (void			*abstract_surface,
 			      cairo_clip_t		*clip)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return surface->xcb->base.backend->fill (surface->xcb,
-					     op, source, path,
-					     fill_rule, tolerance, antialias,
-					     clip);
+    return _cairo_surface_fill (&surface->xcb->base,
+				op, source, path,
+				fill_rule, tolerance,
+				antialias, clip);
 }
 
 static cairo_int_status_t
@@ -188,9 +187,12 @@ _cairo_xlib_xcb_surface_glyphs (void			*abstract_surface,
 				int *num_remaining)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return surface->xcb->base.backend->show_glyphs (surface->xcb, op, source,
-						    glyphs, num_glyphs, scaled_font,
-						    clip, num_remaining);
+    *num_remaining = 0;
+    return _cairo_surface_show_text_glyphs (&surface->xcb->base, op, source,
+					    NULL, 0,
+					    glyphs, num_glyphs,
+					    NULL, 0, 0,
+					    scaled_font, clip);
 }
 
 static cairo_status_t
@@ -208,7 +210,8 @@ _cairo_xlib_xcb_surface_mark_dirty (void *abstract_surface,
 				    int width, int height)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return surface->xcb->base.backend->mark_dirty_rectangle (surface->xcb, x, y, width, height);
+    cairo_surface_mark_dirty_rectangle (&surface->xcb->base, x, y, width, height);
+    return cairo_surface_status (&surface->xcb->base);
 }
 
 static const cairo_surface_backend_t _cairo_xlib_xcb_surface_backend = {
commit 9e4c73a40d6eb72a5110936ab310acbaef99baa8
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Jul 2 23:00:24 2011 +0200

    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 at znc.in>

diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 0462e03..07c2735 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;
commit 880566e14b335ddb5bf1c768f6ca4f02b2dd2add
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Jul 2 17:40:36 2011 +0200

    xcb: Remove an unused function argument
    
    Since commit f1d313e0, the 'force' argument to _copy_to_picture() isn't used
    anymore. Said commit should have removed it. Whoops.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index d1f2288..ad7454f 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -989,8 +989,7 @@ setup_picture:
 }
 
 static cairo_xcb_picture_t *
-_copy_to_picture (cairo_xcb_surface_t *source,
-		  cairo_bool_t force)
+_copy_to_picture (cairo_xcb_surface_t *source)
 {
     cairo_xcb_picture_t *picture;
     uint32_t values[] = { 0, 1 };
@@ -1058,7 +1057,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
     {
 	if (source->backend->type == CAIRO_SURFACE_TYPE_XCB) {
 	    if (((cairo_xcb_surface_t *) source)->screen == target->screen) {
-		picture = _copy_to_picture ((cairo_xcb_surface_t *) source, FALSE);
+		picture = _copy_to_picture ((cairo_xcb_surface_t *) source);
 		if (unlikely (picture->base.status))
 		    return picture;
 	    }
@@ -1070,7 +1069,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 	    if (FALSE && xcb->screen == target->screen) {
 		xcb_rectangle_t rect;
 
-		picture = _copy_to_picture (xcb, TRUE);
+		picture = _copy_to_picture (xcb);
 		if (unlikely (picture->base.status))
 		    return picture;
 
@@ -1093,7 +1092,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 	    cairo_xcb_surface_t *xcb = (cairo_xcb_surface_t *) snap->target;
 
 	    if (xcb->screen == target->screen) {
-		picture = _copy_to_picture (xcb, TRUE);
+		picture = _copy_to_picture (xcb);
 		if (unlikely (picture->base.status))
 		    return picture;
 	    }
@@ -1104,8 +1103,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
     {
 	if (source->backend->type == CAIRO_SURFACE_TYPE_XLIB) {
 	    if (((cairo_xlib_xcb_surface_t *) source)->xcb->screen == target->screen) {
-		picture = _copy_to_picture (((cairo_xlib_xcb_surface_t *) source)->xcb,
-					    FALSE);
+		picture = _copy_to_picture (((cairo_xlib_xcb_surface_t *) source)->xcb);
 		if (unlikely (picture->base.status))
 		    return picture;
 	    }
@@ -1116,7 +1114,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 	    if (FALSE && xcb->screen == target->screen) {
 		xcb_rectangle_t rect;
 
-		picture = _copy_to_picture (xcb, TRUE);
+		picture = _copy_to_picture (xcb);
 		if (unlikely (picture->base.status))
 		    return picture;
 
@@ -1139,7 +1137,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 	    cairo_xcb_surface_t *xcb = ((cairo_xlib_xcb_surface_t *) snap->target)->xcb;
 
 	    if (xcb->screen == target->screen) {
-		picture = _copy_to_picture (xcb, TRUE);
+		picture = _copy_to_picture (xcb);
 		if (unlikely (picture->base.status))
 		    return picture;
 	    }
@@ -1208,7 +1206,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 	    return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status);
 	}
 
-	picture = _copy_to_picture (tmp, FALSE);
+	picture = _copy_to_picture (tmp);
 	cairo_surface_destroy (&tmp->base);
 
 	if (unlikely (picture->base.status))


More information about the cairo-commit mailing list