[cairo] [PATCH] xcb: Fix error reporting if fallback fails
Bryce Harrington
bryce at osg.samsung.com
Wed Jun 7 00:51:06 UTC 2017
On Tue, May 30, 2017 at 06:24:22PM +0200, Uli Schlachter wrote:
> If we cannot let the X11 server do some operation (for example: the
> RENDER extension is not available), then we fall back to an image
> surface and do the operation locally instead. This fallback requires the
> current content of the surface to be downloaded from the X11 server.
> This fallback logic had an error.
>
> The fallback is implemented with _get_image() in the function
> _cairo_xcb_surface_fallback(). _get_image() is only called if we do not
> yet have a fallback available, so when we call _get_image we have
> surface->fallback == NULL. Then, if _get_image() fails, it returns a
> surface in an error state.
>
> Before this patch, the code would then just ignore this error surface
> and return &surface->fallback->base, a NULL pointer. This would then
> quickly cause a crash when e.g. the surface's ->status member is
> accessed.
>
> Fix this by returning the error surface instead as the fallback.
>
> The end result of this patch will be that the XCB surface that is
> currently drawn to ends up in an error state which is a lot better than
> a NULL pointer dereference and actually correct in this case. The error
> state is reached because the current drawing operation will fail and
> this error is reported up the call stack and eventually "taints" the
> surface.
>
> (However, the error code could be better: _get_image() too often fails
> with a generic CAIRO_STATUS_NO_MEMORY error, but that's left as future
> work)
>
> Signed-off-by: Uli Schlachter <psychon at znc.in>
> ---
>
> [No test for this since in the case were I ran into this, _get_image()
> failed because the X11 server closed the connection. No idea why it
> did that.]
Steps to repro the issue (or a bug # if it's been reported) might be
nice, but the change looks sensible enough so:
Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
> src/cairo-xcb-surface.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
> index b319b7f24..39127c148 100644
> --- a/src/cairo-xcb-surface.c
> +++ b/src/cairo-xcb-surface.c
> @@ -833,12 +833,13 @@ _cairo_xcb_surface_fallback (cairo_xcb_surface_t *surface,
> image = (cairo_image_surface_t *)
> _get_image (surface, TRUE, 0, 0, surface->width, surface->height);
>
> + if (image->base.status != CAIRO_STATUS_SUCCESS)
> + return &image->base;
> +
> /* If there was a deferred clear, _get_image applied it */
> - if (image->base.status == CAIRO_STATUS_SUCCESS) {
> - surface->deferred_clear = FALSE;
> + surface->deferred_clear = FALSE;
>
> - surface->fallback = image;
> - }
> + surface->fallback = image;
>
> return &surface->fallback->base;
> }
> --
> 2.11.0
> --
> cairo mailing list
> cairo at cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
More information about the cairo
mailing list