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:
Chris Wilson 2008-10-16 12:19:09 +01:00
parent 9529699028
commit 901f0b540c
6 changed files with 39 additions and 26 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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;