[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