Bug 1293598 - clean up pointers after free inside pixman_image, r?jrmuizel
MozReview-Commit-ID: ChUb4RYUabN
--- a/gfx/cairo/libpixman/src/pixman-image.c
+++ b/gfx/cairo/libpixman/src/pixman-image.c
@@ -28,16 +28,41 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "pixman-private.h"
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
+/**
+ ** bug 1293598 - clean up every pointer after free to avoid
+ ** "dereferencing freed memory" problem
+ **/
+#define PIXMAN_POSION
+
+static void
+free_memory_withoffset (void** p, int offset)
+{
+#ifdef PIXMAN_POISON
+ if (*p) {
+#endif
+ free (*p + offset);
+#ifdef PIXMAN_POISON
+ *p = NULL;
+ }
+#endif
+}
+
+static void
+free_memory (void** p)
+{
+ free_memory_withoffset (p, 0);
+}
+
static void
gradient_property_changed (pixman_image_t *image)
{
gradient_t *gradient = &image->gradient;
int n = gradient->n_stops;
pixman_gradient_stop_t *stops = gradient->stops;
pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
pixman_gradient_stop_t *end = &(gradient->stops[n]);
@@ -140,42 +165,45 @@ pixman_bool_t
if (common->ref_count == 0)
{
if (image->common.destroy_func)
image->common.destroy_func (image, image->common.destroy_data);
pixman_region32_fini (&common->clip_region);
- free (common->transform);
- free (common->filter_params);
+ free_memory (&common->transform);
+ free_memory (&common->filter_params);
if (common->alpha_map)
pixman_image_unref ((pixman_image_t *)common->alpha_map);
if (image->type == LINEAR ||
image->type == RADIAL ||
image->type == CONICAL)
{
if (image->gradient.stops)
{
/* See _pixman_init_gradient() for an explanation of the - 1 */
- free (image->gradient.stops - 1);
+ free_memory_withoffset (&image->gradient.stops, -1);
}
/* This will trigger if someone adds a property_changed
* method to the linear/radial/conical gradient overwriting
* the general one.
*/
assert (
image->common.property_changed == gradient_property_changed);
}
- if (image->type == BITS && image->bits.free_me)
- free (image->bits.free_me);
+ if (image->type == BITS && image->bits.free_me) {
+ free_memory (&image->bits.free_me);
+ image->bits.bits = NULL;
+ }
+
return TRUE;
}
return FALSE;
}
pixman_image_t *
@@ -205,17 +233,17 @@ pixman_image_ref (pixman_image_t *image)
}
/* returns TRUE when the image is freed */
PIXMAN_EXPORT pixman_bool_t
pixman_image_unref (pixman_image_t *image)
{
if (_pixman_image_fini (image))
{
- free (image);
+ free_memory (&image);
return TRUE;
}
return FALSE;
}
PIXMAN_EXPORT void
pixman_image_set_destroy_function (pixman_image_t * image,