[cairo-commit] 6 commits - src/cairo-array.c src/cairo-bentley-ottmann.c src/cairo-ft-font.c src/cairo-gstate.c src/cairo-hull.c src/cairo-image-surface.c src/cairo-malloc-private.h src/cairo-misc.c src/cairo-path-stroke.c src/cairo-pattern.c src/cairo-pen.c src/cairo-polygon.c src/cairo-scaled-font.c src/cairo-stroke-style.c src/cairo-traps.c test/cairo-test.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Apr 23 01:26:52 PDT 2009


 src/cairo-array.c           |    3 +
 src/cairo-bentley-ottmann.c |    3 +
 src/cairo-ft-font.c         |   94 +++++++++++++++++++++++++-------------------
 src/cairo-gstate.c          |    3 +
 src/cairo-hull.c            |    3 +
 src/cairo-image-surface.c   |    6 ++
 src/cairo-malloc-private.h  |    7 +++
 src/cairo-misc.c            |    3 +
 src/cairo-path-stroke.c     |    2 
 src/cairo-pattern.c         |   12 +++++
 src/cairo-pen.c             |    9 ++++
 src/cairo-polygon.c         |    5 ++
 src/cairo-scaled-font.c     |    3 +
 src/cairo-stroke-style.c    |    3 +
 src/cairo-traps.c           |    5 ++
 test/cairo-test.c           |    6 ++
 16 files changed, 127 insertions(+), 40 deletions(-)

New commits:
commit 1ae2ddc1dd4c90d50b8c57c4de677f8ab96b1fa2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 16 17:19:12 2009 +0100

    [memfault] Manually inject faults when using stack allocations
    
    Ensure that no assumptions are made that a small allocation will succeed
    by manually injecting faults when we may be simply allocating from an
    embedded memory pool.
    
    The main advantage in manual fault injection is improved code coverage -
    from within the test suite most allocations are handled by the embedded
    memory pools.

diff --git a/src/cairo-array.c b/src/cairo-array.c
index 318fd07..77e575f 100644
--- a/src/cairo-array.c
+++ b/src/cairo-array.c
@@ -125,6 +125,9 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
     if (required_size > INT_MAX || required_size < array->num_elements)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     if (required_size <= old_size)
 	return CAIRO_STATUS_SUCCESS;
 
diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 81eed1d..1d59d70 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -1660,6 +1660,9 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t	 *traps,
     if (0 == polygon->num_edges)
 	return CAIRO_STATUS_SUCCESS;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     has_limits = _cairo_traps_get_limit (traps, &limit);
 
     edges = stack_edges;
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 9ee31b0..c7c4cf5 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -222,6 +222,9 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
     cairo_gstate_t *top;
     cairo_status_t status;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     top = *freelist;
     if (top == NULL) {
 	top = malloc (sizeof (cairo_gstate_t));
diff --git a/src/cairo-hull.c b/src/cairo-hull.c
index a699a52..1fa919b 100644
--- a/src/cairo-hull.c
+++ b/src/cairo-hull.c
@@ -198,6 +198,9 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices)
     cairo_hull_t *hull;
     int num_hull = *num_vertices;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     if (num_hull > ARRAY_LENGTH (hull_stack)) {
 	hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t));
 	if (unlikely (hull == NULL))
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 746fca1..b601ac4 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1044,6 +1044,9 @@ _cairo_image_surface_fill_rectangles (void		      *abstract_surface,
 
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     pixman_color.red   = color->red_short;
     pixman_color.green = color->green_short;
     pixman_color.blue  = color->blue_short;
@@ -1112,6 +1115,9 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t	op,
     if (height == 0 || width == 0)
 	return CAIRO_STATUS_SUCCESS;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     /* Convert traps to pixman traps */
     if (num_traps > ARRAY_LENGTH (stack_traps)) {
 	pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t));
diff --git a/src/cairo-malloc-private.h b/src/cairo-malloc-private.h
index f8094f9..e36f93b 100644
--- a/src/cairo-malloc-private.h
+++ b/src/cairo-malloc-private.h
@@ -39,6 +39,13 @@
 
 #include "cairo-wideint-private.h"
 
+#if HAVE_MEMFAULT
+#include <memfault.h>
+#define CAIRO_INJECT_FAULT() VALGRIND_INJECT_FAULT()
+#else
+#define CAIRO_INJECT_FAULT() 0
+#endif
+
 /**
  * _cairo_malloc:
  * @size: size in bytes
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index aaf849b..d4b10e1 100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -704,6 +704,9 @@ _cairo_intern_string (const char **str_inout, int len)
     cairo_intern_string_t tmpl, *istring;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     if (len < 0)
 	len = strlen (str);
     tmpl.hash_entry.hash = _intern_string_hash (str, len);
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index d6e5790..37ac79c 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -1278,6 +1278,8 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
 					cairo_bool_t		 is_horizontal,
 					cairo_bool_t		 has_join)
 {
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (stroker->num_segments == stroker->segments_size) {
 	int new_size = stroker->segments_size * 2;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 81fd567..0fb36bf 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -119,6 +119,9 @@ static cairo_status_t
 _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t	  *pattern,
 				   const cairo_gradient_pattern_t *other)
 {
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR)
     {
 	cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern;
@@ -841,6 +844,9 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
 	return CAIRO_STATUS_SUCCESS;
     }
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     assert (pattern->n_stops <= pattern->stops_size);
 
     if (pattern->stops == pattern->stops_embedded) {
@@ -1257,6 +1263,9 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
     int clone_offset_x, clone_offset_y;
     cairo_matrix_t matrix = pattern->base.matrix;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
 	pixman_stops = _cairo_malloc_ab (pattern->n_stops,
 					 sizeof(pixman_gradient_stop_t));
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 9d5e895..eb66b1a 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -55,6 +55,9 @@ _cairo_pen_init (cairo_pen_t	*pen,
     int i;
     int reflect;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     pen->radius = radius;
     pen->tolerance = tolerance;
 
@@ -109,6 +112,9 @@ _cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other)
 {
     *pen = *other;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     pen->vertices = pen->vertices_embedded;
     if (pen->num_vertices) {
 	if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
@@ -132,6 +138,9 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
     int num_vertices;
     int i;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     num_vertices = pen->num_vertices + num_points;
     if (num_vertices > ARRAY_LENGTH (pen->vertices_embedded) ||
 	pen->vertices != pen->vertices_embedded)
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index 0b0fa99..d74d098 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -64,6 +64,11 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
     int old_size = polygon->edges_size;
     int new_size = 4 * old_size;
 
+    if (CAIRO_INJECT_FAULT ()) {
+	polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return FALSE;
+    }
+
     if (polygon->edges == polygon->edges_embedded) {
 	new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t));
 	if (new_edges != NULL)
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 249ab6c..b8d9602 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -2558,6 +2558,9 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
     if (unlikely (scaled_font->status))
 	return scaled_font->status;
 
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     /*
      * Check cache for glyph
      */
diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c
index d808ad8..462b868 100644
--- a/src/cairo-stroke-style.c
+++ b/src/cairo-stroke-style.c
@@ -52,6 +52,9 @@ cairo_status_t
 _cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
 			       cairo_stroke_style_t *other)
 {
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     style->line_width = other->line_width;
     style->line_cap = other->line_cap;
     style->line_join = other->line_join;
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index faf7722..fed3f10 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -131,6 +131,11 @@ _cairo_traps_grow (cairo_traps_t *traps)
     cairo_trapezoid_t *new_traps;
     int new_size = 2 * MAX (traps->traps_size, 16);
 
+    if (CAIRO_INJECT_FAULT ()) {
+	traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return FALSE;
+    }
+
     if (traps->traps == traps->traps_embedded) {
 	new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t));
 	if (new_traps != NULL)
commit 817589e1967ebdd5e5bda1781eb76010fd8c37dc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 16 13:01:52 2009 +0100

    [test] Call FcInit() manually.
    
    Pre-initialise fontconfig whilst memfault is disabled to avoid a lot of
    expensive, redundant testing of FcInit() throughout the test suite.

diff --git a/test/cairo-test.c b/test/cairo-test.c
index 897332a..96ab2dc 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -743,6 +743,12 @@ REPEAT:
     VALGRIND_RESET_LEAKS ();
     ctx->last_fault_count = 0;
     last_fault_count = VALGRIND_COUNT_FAULTS ();
+
+    /* Pre-initialise fontconfig so that the configuration is loaded without
+     * malloc failures (our primary goal is to test cairo fault tolerance).
+     */
+    FcInit ();
+
     VALGRIND_ENABLE_FAULTS ();
 #endif
     have_output = FALSE;
commit be27e844c83c0f5cf25dee1c62768dbf70897a06
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 16 17:13:52 2009 +0100

    [ft] Propagate status from font creation
    
    Return the true error status whel
    _cairo_ft_unscaled_font_create_internal(). This ensures that the original
    error is not masked and we are able to report the error during fontconfig
    pattern resolution.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index f5b3330..e701c21 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -414,11 +414,12 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a,
 /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
  * pattern.  Returns a new reference to the unscaled font.
  */
-static cairo_ft_unscaled_font_t *
+static cairo_status_t
 _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
 					 char *filename,
 					 int id,
-					 FT_Face font_face)
+					 FT_Face font_face,
+					 cairo_ft_unscaled_font_t **out)
 {
     cairo_ft_unscaled_font_t key, *unscaled;
     cairo_ft_unscaled_font_map_t *font_map;
@@ -426,7 +427,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
 
     font_map = _cairo_ft_unscaled_font_map_lock ();
     if (unlikely (font_map == NULL))
-	goto UNWIND;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
 
@@ -435,14 +436,13 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
 					 &key.base.hash_entry);
     if (unscaled != NULL) {
 	_cairo_unscaled_font_reference (&unscaled->base);
-	_cairo_ft_unscaled_font_map_unlock ();
-	return unscaled;
+	goto DONE;
     }
 
     /* Otherwise create it and insert into hash table. */
     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
     if (unlikely (unscaled == NULL)) {
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto UNWIND_FONT_MAP_LOCK;
     }
 
@@ -456,9 +456,10 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
     if (unlikely (status))
 	goto UNWIND_UNSCALED_FONT_INIT;
 
+DONE:
     _cairo_ft_unscaled_font_map_unlock ();
-
-    return unscaled;
+    *out = unscaled;
+    return CAIRO_STATUS_SUCCESS;
 
 UNWIND_UNSCALED_FONT_INIT:
     _cairo_ft_unscaled_font_fini (unscaled);
@@ -466,39 +467,52 @@ UNWIND_UNSCALED_MALLOC:
     free (unscaled);
 UNWIND_FONT_MAP_LOCK:
     _cairo_ft_unscaled_font_map_unlock ();
-UNWIND:
-    return NULL;
+    return status;
 }
 
 
 #if CAIRO_HAS_FC_FONT
-static cairo_ft_unscaled_font_t *
-_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
+static cairo_status_t
+_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern,
+					    cairo_ft_unscaled_font_t **out)
 {
     FT_Face font_face = NULL;
     char *filename = NULL;
     int id = 0;
+    FcResult ret;
 
-    if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face) == FcResultMatch)
-	goto DONE;
-
-    if (FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename) == FcResultMatch) {
-	/* If FC_INDEX is not set, we just use 0 */
-        FcPatternGetInteger (pattern, FC_INDEX, 0, &id);
+    ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face);
+    switch ((int) ret) {
+    case FcResultMatch:
 	goto DONE;
+    case FcResultOutOfMemory:
+	break;
+    default:
+	if (FcPatternGetString (pattern, FC_FILE, 0,
+				(FcChar8 **) &filename) == FcResultMatch)
+	{
+	    /* If FC_INDEX is not set, we just use 0 */
+	    if (FcPatternGetInteger (pattern,
+				     FC_INDEX, 0, &id) != FcResultOutOfMemory)
+		goto DONE;
+	}
+	break;
     }
 
-    return NULL;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 DONE:
-    return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face);
+    return _cairo_ft_unscaled_font_create_internal (font_face != NULL,
+						    filename, id, font_face,
+						    out);
 }
 #endif
 
-static cairo_ft_unscaled_font_t *
-_cairo_ft_unscaled_font_create_from_face (FT_Face face)
+static cairo_status_t
+_cairo_ft_unscaled_font_create_from_face (FT_Face face,
+					  cairo_ft_unscaled_font_t **out)
 {
-    return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face);
+    return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out);
 }
 
 static void
@@ -2311,7 +2325,6 @@ _cairo_ft_font_face_scaled_font_create (void                     *abstract_face,
 	    *scaled_font = _cairo_scaled_font_create_in_error (status);
 	    return CAIRO_STATUS_SUCCESS;
 	}
-
     } else
 #endif
     {
@@ -2319,11 +2332,11 @@ _cairo_ft_font_face_scaled_font_create (void                     *abstract_face,
 	ft_options = font_face->ft_options;
     }
 
-    return  _cairo_ft_scaled_font_create (unscaled,
-					  &font_face->base,
-					  font_matrix, ctm,
-					  options, ft_options,
-					  scaled_font);
+    return _cairo_ft_scaled_font_create (unscaled,
+					 &font_face->base,
+					 font_matrix, ctm,
+					 options, ft_options,
+					 scaled_font);
 }
 
 const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
@@ -2583,11 +2596,9 @@ _cairo_ft_resolve_pattern (FcPattern		      *pattern,
 	goto FREE_PATTERN;
     }
 
-    *unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
-    if (!*unscaled) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_ft_unscaled_font_create_for_pattern (resolved, unscaled);
+    if (unlikely (status))
 	goto FREE_RESOLVED;
-    }
 
     _get_pattern_ft_options (resolved, ft_options);
 
@@ -2643,10 +2654,12 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
     cairo_ft_unscaled_font_t *unscaled;
     cairo_font_face_t *font_face;
     cairo_ft_options_t ft_options;
+    cairo_status_t status;
 
-    unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
+    status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled);
+    if (unlikely (status))
+	return (cairo_font_face_t *) &_cairo_font_face_nil;
     if (unlikely (unscaled == NULL)) {
-	cairo_status_t status;
 	/* Store the pattern.  We will resolve it and create unscaled
 	 * font when creating scaled fonts */
 	status = _cairo_ft_font_face_create_for_pattern (pattern,
@@ -2718,12 +2731,11 @@ cairo_ft_font_face_create_for_ft_face (FT_Face         face,
     cairo_ft_unscaled_font_t *unscaled;
     cairo_font_face_t *font_face;
     cairo_ft_options_t ft_options;
+    cairo_status_t status;
 
-    unscaled = _cairo_ft_unscaled_font_create_from_face (face);
-    if (unlikely (unscaled == NULL)) {
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled);
+    if (unlikely (status))
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
 
     ft_options.load_flags = load_flags;
     ft_options.extra_flags = 0;
commit d46c56f18c8a93d3d50be9333292c7c9b0ac0a78
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 16 13:00:59 2009 +0100

    [ft] Check for pattern duplication failure.
    
    Check the return of FcPatternDuplicate() for failure, and propagate the
    error.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 6e9d5f9..f5b3330 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2558,6 +2558,8 @@ _cairo_ft_resolve_pattern (FcPattern		      *pattern,
 	return status;
 
     pattern = FcPatternDuplicate (pattern);
+    if (pattern == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
commit 50302f156dfba4dcb3639843d7eda819f2c6797c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 16 12:59:36 2009 +0100

    [ft] Check (correctly!) for pattern duplication failure.
    
    Check the return from FcPatternDuplicate() for allocation failure (and not
    the original pattern)!

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 3cfe344..6e9d5f9 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2352,7 +2352,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
     font_face->next = NULL;
 
     font_face->pattern = FcPatternDuplicate (pattern);
-    if (unlikely (pattern == NULL)) {
+    if (unlikely (font_face->pattern == NULL)) {
 	free (font_face);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
commit 8bf109bd2a9c9bf755671185733def898a4f96f2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 16 17:17:06 2009 +0100

    [pattern] Silence compiler with impossible case.
    
    Assert that the pattern is one of the four known types, and return an
    error so that the compiler knows that the local variable can not be used
    uninitialised.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 0ecfbe3..81fd567 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -272,6 +272,9 @@ _cairo_pattern_create_copy (cairo_pattern_t	  **pattern_out,
     case CAIRO_PATTERN_TYPE_RADIAL:
 	pattern = malloc (sizeof (cairo_radial_pattern_t));
 	break;
+    default:
+	ASSERT_NOT_REACHED;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
     }
     if (unlikely (pattern == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);


More information about the cairo-commit mailing list