mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-23 04:00:41 +02:00
Review backend->create_similar()
Avoid masking fatal errors by enforcing any error to be returned via an error surface, so that the NULL return only means UNSUPPORTED. A few backends called their create_similar() directly, without correctly checking for a potential NULL (for example, the directfb backend was a timebomb, since it used NULL to indicate out-of-memory).
This commit is contained in:
parent
9529699028
commit
901f0b540c
6 changed files with 39 additions and 26 deletions
|
|
@ -456,10 +456,8 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
|
|||
|
||||
format = _cairo_format_from_content (content);
|
||||
surface = calloc (1, sizeof(cairo_directfb_surface_t));
|
||||
if (!surface) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
if (surface == NULL)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
|
||||
surface->dfb = source->dfb;
|
||||
|
||||
|
|
@ -644,8 +642,10 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
|
|||
_cairo_directfb_surface_create_similar (surface,
|
||||
_cairo_content_from_format (image_src->format),
|
||||
image_src->width, image_src->height);
|
||||
if (!clone)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
if (clone == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (clone->base.status)
|
||||
return clone->base.status;
|
||||
|
||||
ret = clone->dfbsurface->Lock (clone->dfbsurface,
|
||||
DSLF_WRITE, (void *)&dst, &pitch);
|
||||
|
|
@ -766,8 +766,10 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
|||
if (!dst->color) {
|
||||
dst->color = _cairo_directfb_surface_create_similar (dst,
|
||||
CAIRO_CONTENT_COLOR_ALPHA, 1, 1);
|
||||
if (!dst->color)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
if (dst->color == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (dst->color->base.status)
|
||||
return (dst->color->base.status);
|
||||
}
|
||||
|
||||
src = (cairo_directfb_surface_t *)dst->color;
|
||||
|
|
|
|||
|
|
@ -543,6 +543,8 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
|
|||
_cairo_glitz_surface_create_similar (surface, content,
|
||||
image_src->width,
|
||||
image_src->height);
|
||||
if (clone == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (clone->base.status)
|
||||
return clone->base.status;
|
||||
|
||||
|
|
@ -806,8 +808,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
_cairo_surface_create_similar_scratch (&dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
gradient->n_stops, 1);
|
||||
if (src->base.status)
|
||||
{
|
||||
if (src->base.status) {
|
||||
glitz_buffer_destroy (buffer);
|
||||
free (data);
|
||||
return src->base.status;
|
||||
|
|
@ -1280,8 +1281,13 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
|||
_cairo_glitz_surface_create_similar (&dst->base,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
2, 1);
|
||||
if (mask->base.status)
|
||||
{
|
||||
if (mask == NULL) {
|
||||
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
|
||||
if (src_pattern == &tmp_src_pattern.base)
|
||||
_cairo_pattern_fini (&tmp_src_pattern.base);
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
if (mask->base.status) {
|
||||
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
|
||||
if (src_pattern == &tmp_src_pattern.base)
|
||||
_cairo_pattern_fini (&tmp_src_pattern.base);
|
||||
|
|
@ -1389,8 +1395,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
|||
_cairo_surface_create_similar_scratch (&dst->base,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
width, height);
|
||||
if (mask->base.status)
|
||||
{
|
||||
if (mask->base.status) {
|
||||
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
|
||||
free (data);
|
||||
cairo_surface_destroy (&image->base);
|
||||
|
|
|
|||
|
|
@ -1565,8 +1565,8 @@ _cairo_quartz_surface_create_similar (void *abstract_surface,
|
|||
|
||||
// verify width and height of surface
|
||||
if (!_cairo_quartz_verify_surface_size(width, height)) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
return _cairo_surface_create_in_error (_cairo_error
|
||||
(CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
return cairo_quartz_surface_create (format, width, height);
|
||||
|
|
|
|||
|
|
@ -238,12 +238,8 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
|
|||
|
||||
if (other->backend->create_similar) {
|
||||
surface = other->backend->create_similar (other, content, width, height);
|
||||
/* It's not an error if the backend didn't create a valid
|
||||
* surface---it may just not be supported. */
|
||||
if (surface && surface->status) {
|
||||
cairo_surface_destroy (surface);
|
||||
surface = NULL;
|
||||
}
|
||||
if (surface != NULL && surface->status)
|
||||
return surface;
|
||||
}
|
||||
|
||||
if (surface == NULL)
|
||||
|
|
|
|||
|
|
@ -446,10 +446,16 @@ _cairo_win32_surface_clone_similar (void *abstract_surface,
|
|||
|
||||
src_content = cairo_surface_get_content(src);
|
||||
new_surface =
|
||||
_cairo_win32_surface_create_similar_internal (abstract_surface, src_content, width, height, FALSE);
|
||||
_cairo_win32_surface_create_similar_internal (abstract_surface,
|
||||
src_content,
|
||||
width, height,
|
||||
FALSE);
|
||||
if (new_surface == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (cairo_surface_status(new_surface))
|
||||
return cairo_surface_status(new_surface);
|
||||
status = new_surface->status;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern, src);
|
||||
|
||||
|
|
@ -516,8 +522,10 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
|
|||
local =
|
||||
(cairo_win32_surface_t *) _cairo_win32_surface_create_similar_internal
|
||||
(surface, content, width, height, TRUE);
|
||||
if (local == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (local->base.status)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return local->base.status;
|
||||
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
|
|
|||
|
|
@ -722,6 +722,8 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
|
|||
|
||||
clone = (cairo_xcb_surface_t *)
|
||||
_cairo_xcb_surface_create_similar (surface, content, width, height);
|
||||
if (clone == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (clone->base.status)
|
||||
return clone->base.status;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue