diff -u libcairo-1.4.10/debian/changelog libcairo-1.4.10/debian/changelog
--- libcairo-1.4.10/debian/changelog
+++ libcairo-1.4.10/debian/changelog
@@ -1,3 +1,11 @@
+libcairo (1.4.10-1.1) unstable; urgency=high
+
+  * Non-maintainer upload by testing-security team.
+  * Fix multiple integer overflows leading to arbitrary code
+    execution (CVE-2007-5503; Closes: #453686).
+
+ -- Nico Golde <nion@debian.org>  Mon, 03 Dec 2007 17:20:59 +0100
+
 libcairo (1.4.10-1) unstable; urgency=low
 
   * New upstream release
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-atsui-font.c
+++ libcairo-1.4.10/src/cairo-atsui-font.c
@@ -809,7 +809,7 @@
 
     *num_glyphs = glyphCount - 1;
     *glyphs =
-	(cairo_glyph_t *) malloc(*num_glyphs * (sizeof (cairo_glyph_t)));
+	(cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
     if (*glyphs == NULL) {
 	return CAIRO_STATUS_NO_MEMORY;
     }
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-ft-font.c
+++ libcairo-1.4.10/src/cairo-ft-font.c
@@ -742,7 +742,7 @@
 	    data = bitmap->buffer;
 	    assert (stride == bitmap->pitch);
 	} else {
-	    data = malloc (stride * height);
+	    data = _cairo_malloc_ab (height, stride);
 	    if (!data) {
 		_cairo_error (CAIRO_STATUS_NO_MEMORY);
 		return CAIRO_STATUS_NO_MEMORY;
@@ -792,7 +792,7 @@
 	    if (own_buffer) {
 		data = bitmap->buffer;
 	    } else {
-		data = malloc (stride * height);
+		data = _cairo_malloc_ab (height, stride);
 		if (!data) {
 		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		    return CAIRO_STATUS_NO_MEMORY;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-bentley-ottmann.c
+++ libcairo-1.4.10/src/cairo-bentley-ottmann.c
@@ -754,7 +754,7 @@
      * or stop events, so this allocation is safe.  XXX: make the
      * event type a union so it doesn't always contain the skip
      * elt? */
-    events = malloc (num_events * (sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*)));
+    events = _cairo_malloc_ab (num_events, sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*));
     if (events == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -1436,7 +1436,7 @@
     if (polygon->num_edges < ARRAY_LENGTH (stack_edges)) {
 	edges = stack_edges;
     } else {
-	edges = malloc (polygon->num_edges * sizeof (cairo_bo_edge_t));
+	edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
 	if (edges == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
@@ -1757,7 +1757,7 @@
     while (intersections) {
 	int num_edges = _cairo_array_num_elements (&intersected_edges);
 	passes++;
-	edges = malloc (num_edges * sizeof (cairo_bo_edge_t));
+	edges = _cairo_malloc_ab (num_edges, sizeof (cairo_bo_edge_t));
 	assert (edges != NULL);
 	memcpy (edges, _cairo_array_index (&intersected_edges, 0), num_edges * sizeof (cairo_bo_edge_t));
 	_cairo_array_fini (&intersected_edges);
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-traps.c
+++ libcairo-1.4.10/src/cairo-traps.c
@@ -260,11 +260,12 @@
 	return traps->status;
 
     if (traps->traps == traps->traps_embedded) {
-	new_traps = malloc (new_size * sizeof (cairo_trapezoid_t));
+	new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t));
 	if (new_traps)
 	    memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded));
     } else {
-	new_traps = realloc (traps->traps, new_size * sizeof (cairo_trapezoid_t));
+		new_traps = _cairo_realloc_ab (traps->traps,
+				new_size, sizeof (cairo_trapezoid_t));
     }
 
     if (new_traps == NULL) {
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-malloc-private.h
+++ libcairo-1.4.10/src/cairo-malloc-private.h
@@ -0,0 +1,126 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright Â© 2007 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ *
+ * Contributor(s):
+ *	Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#ifndef CAIRO_MALLOC_PRIVATE_H
+#define CAIRO_MALLOC_PRIVATE_H
+
+#include "cairo-wideint-private.h"
+
+/**
+ * _cairo_malloc_ab:
+ * @n: number of elements to allocate
+ * @size: size of each element
+ *
+ * Allocates @n*@size memory using malloc(), taking care to not
+ * overflow when doing the multiplication.  Behaves much like
+ * calloc(), except that the returned memory is not set to zero.
+ * The memory should be freed using free().
+ *
+ * @size should be a constant so that the compiler can optimize
+ * out a constant division.
+ *
+ * Return value: A pointer to the newly allocated memory, or %NULL in
+ * case of malloc() failure or overflow.
+ */
+
+#define _cairo_malloc_ab(a, size) \
+  ((unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   malloc((unsigned) (a) * (unsigned) (size)))
+
+/**
+ * _cairo_realloc_ab:
+ * @ptr: original pointer to block of memory to be resized
+ * @n: number of elements to allocate
+ * @size: size of each element
+ *
+ * Reallocates @ptr a block of @n*@size memory using realloc(), taking
+ * care to not overflow when doing the multiplication.  The memory
+ * should be freed using free().
+ *
+ * @size should be a constant so that the compiler can optimize
+ * out a constant division.
+ *
+ * Return value: A pointer to the newly allocated memory, or %NULL in
+ * case of realloc() failure or overflow (whereupon the original block
+ * of memory * is left untouched).
+ */
+
+#define _cairo_realloc_ab(ptr, a, size) \
+  ((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   realloc(ptr, (unsigned) (a) * (unsigned) (size)))
+
+/**
+ * _cairo_malloc_abc:
+ * @n: first factor of number of elements to allocate
+ * @b: second factor of number of elements to allocate
+ * @size: size of each element
+ *
+ * Allocates @n*@b*@size memory using malloc(), taking care to not
+ * overflow when doing the multiplication.  Behaves like
+ * _cairo_malloc_ab().  The memory should be freed using free().
+ *
+ * @size should be a constant so that the compiler can optimize
+ * out a constant division.
+ *
+ * Return value: A pointer to the newly allocated memory, or %NULL in
+ * case of malloc() failure or overflow.
+ */
+
+#define _cairo_malloc_abc(a, b, size) \
+  ((unsigned) (a) >= INT32_MAX / (unsigned) (b) ? NULL : \
+   (unsigned) ((a)*(b)) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   malloc((unsigned) (a) * (unsigned) (b) * (unsigned) size))
+
+/**
+ * _cairo_malloc_ab_plus_c:
+ * @n: number of elements to allocate
+ * @size: size of each element
+ * @k: additional size to allocate
+ *
+ * Allocates @n*@ksize+@k memory using malloc(), taking care to not
+ * overflow when doing the arithmetic.  Behaves like
+ * _cairo_malloc_ab().  The memory should be freed using free().
+ *
+ * Return value: A pointer to the newly allocated memory, or %NULL in
+ * case of malloc() failure or overflow.
+ */
+
+#define _cairo_malloc_ab_plus_c(n, size, k) \
+  ((unsigned) (n) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   (unsigned) (k) >= INT32_MAX - (unsigned) (n) * (unsigned) (size) ? NULL : \
+   malloc((unsigned) (n) * (unsigned) (size) + (unsigned) (k)))
+
+#endif /* CAIRO_MALLOC_PRIVATE_H */
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-os2-surface.c
+++ libcairo-1.4.10/src/cairo-os2-surface.c
@@ -296,8 +296,9 @@
         ULONG ulPixels;
 
         /* allocate temporary pixel buffer */
-        pchPixBuf = (unsigned char *) malloc (3 * surface->bitmap_info.cx *
-                                              surface->bitmap_info.cy);
+        pchPixBuf = (unsigned char *) _cairo_malloc_abc (surface->bitmap_info.cy,
+						      surface->bitmap_info.cx,
+						      3);
         pchPixSource = surface->pixels; /* start at beginning of pixel buffer */
         pBufStart = pchPixBuf; /* remember beginning of the new pixel buffer */
 
@@ -713,7 +714,7 @@
     local_os2_surface->bitmap_info.cBitCount = 32;
 
     /* Allocate memory for pixels */
-    local_os2_surface->pixels = (unsigned char *) malloc (width * height * 4);
+    local_os2_surface->pixels = (unsigned char *) _cairo_malloc_abc (height, width, 4);
     if (!(local_os2_surface->pixels)) {
         /* Not enough memory for the pixels! */
         DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
@@ -783,7 +784,7 @@
     }
 
     /* Allocate memory for new stuffs */
-    pchNewPixels = (unsigned char *) malloc (new_width * new_height * 4);
+    pchNewPixels = (unsigned char *) _cairo_malloc_abc (new_height, new_width, 4);
     if (!pchNewPixels) {
         /* Not enough memory for the pixels!
          * Everything remains the same!
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-lzw.c
+++ libcairo-1.4.10/src/cairo-lzw.c
@@ -93,7 +93,11 @@
     if (buf->status)
 	return buf->status;
 
-    new_data = realloc (buf->data, new_size);
+	new_data = NULL;
+	/* check for integer overflow */
+	if (new_size / 2 == buf->data_size)
+		new_data = realloc (buf->data, new_size);
+
     if (new_data == NULL) {
 	free (buf->data);
 	buf->data_size = 0;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-gstate.c
+++ libcairo-1.4.10/src/cairo-gstate.c
@@ -530,7 +530,7 @@
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    gstate->stroke_style.dash = malloc (gstate->stroke_style.num_dashes * sizeof (double));
+    gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
     if (gstate->stroke_style.dash == NULL) {
 	gstate->stroke_style.num_dashes = 0;
 	return CAIRO_STATUS_NO_MEMORY;
@@ -1570,7 +1570,7 @@
     if (num_glyphs <= STACK_GLYPHS_LEN) {
 	transformed_glyphs = stack_transformed_glyphs;
     } else {
-	transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
+	transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
 	if (transformed_glyphs == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
@@ -1615,7 +1615,7 @@
     if (num_glyphs < STACK_GLYPHS_LEN)
       transformed_glyphs = stack_transformed_glyphs;
     else
-      transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
+      transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
     if (transformed_glyphs == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-pattern.c
+++ libcairo-1.4.10/src/cairo-pattern.c
@@ -133,8 +133,8 @@
 	pattern->stops = pattern->stops_embedded;
     else if (other->stops)
     {
-	pattern->stops = malloc (other->stops_size *
-				 sizeof (pixman_gradient_stop_t));
+	pattern->stops = _cairo_malloc_ab (other->stops_size,
+					 sizeof (pixman_gradient_stop_t));
 	if (pattern->stops == NULL) {
 	    pattern->stops_size = 0;
 	    pattern->n_stops = 0;
@@ -757,11 +757,12 @@
     assert (pattern->n_stops <= pattern->stops_size);
 
     if (pattern->stops == pattern->stops_embedded) {
-	new_stops = malloc (new_size * sizeof (pixman_gradient_stop_t));
+	new_stops = _cairo_malloc_ab (new_size, sizeof (pixman_gradient_stop_t));
 	if (new_stops)
 	    memcpy (new_stops, pattern->stops, old_size * sizeof (pixman_gradient_stop_t));
     } else {
-	new_stops = realloc (pattern->stops, new_size * sizeof (pixman_gradient_stop_t));
+		new_stops = _cairo_realloc_ab (pattern->stops, new_size,
+				sizeof (pixman_gradient_stop_t));
     }
 
     if (new_stops == NULL) {
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-clip.c
+++ libcairo-1.4.10/src/cairo-clip.c
@@ -634,9 +634,13 @@
         return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 
     n_boxes = clip->has_region ? pixman_region_num_rects (&clip->region) : 1;
-    rectangles = malloc (sizeof (cairo_rectangle_t)*n_boxes);
-    if (rectangles == NULL)
-        return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+    if (n_boxes > 0) {
+	rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
+	if (rectangles == NULL)
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+    } else {
+	rectangles = NULL;
+    }
 
     if (clip->has_region) {
         pixman_box16_t *boxes;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-beos-surface.cpp
+++ libcairo-1.4.10/src/cairo-beos-surface.cpp
@@ -259,7 +259,7 @@
 		  int            height,
 		  int            stride)
 {
-    unsigned char* retdata = reinterpret_cast<unsigned char*>(malloc(stride * height));
+    unsigned char* retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
     if (!retdata)
 	return NULL;
 
@@ -322,7 +322,7 @@
 					bitmap->BytesPerRow());
     } else {
 	premultiplied = reinterpret_cast<unsigned char*>(
-					malloc(bitmap->BytesPerRow() * height));
+					_cairo_malloc_ab(bitmap->BytesPerRow(), height));
 	if (premultiplied)
 	    memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
     }
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-surface.c
+++ libcairo-1.4.10/src/cairo-surface.c
@@ -1245,7 +1245,7 @@
 
     rects = stack_rects;
     if (num_rects > ARRAY_LENGTH (stack_rects)) {
-	rects = malloc (sizeof (cairo_rectangle_int16_t) * num_rects);
+	rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int16_t));
 	if (!rects)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-stroke-style.c
+++ libcairo-1.4.10/src/cairo-stroke-style.c
@@ -62,7 +62,7 @@
     if (other->dash == NULL) {
 	style->dash = NULL;
     } else {
-	style->dash = malloc (style->num_dashes * sizeof (double));
+	style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double));
 	if (style->dash == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-svg-surface.c
+++ libcairo-1.4.10/src/cairo-svg-surface.c
@@ -1220,7 +1220,7 @@
 
     if (emulate_reflect || reverse_stops) {
 	n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops;
-	stops = malloc (sizeof (pixman_gradient_stop_t) * n_stops);
+	stops = _cairo_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
 
 	for (i = 0; i < pattern->n_stops; i++) {
 	    if (reverse_stops) {
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-polygon.c
+++ libcairo-1.4.10/src/cairo-polygon.c
@@ -93,11 +93,12 @@
     assert (polygon->num_edges <= polygon->edges_size);
 
     if (polygon->edges == polygon->edges_embedded) {
-	new_edges = malloc (new_size * sizeof (cairo_edge_t));
+	new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t));
 	if (new_edges)
 	    memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t));
     } else {
-	new_edges = realloc (polygon->edges, new_size * sizeof (cairo_edge_t));
+		new_edges = _cairo_realloc_ab (polygon->edges,
+				new_size, sizeof (cairo_edge_t));
     }
 
     if (new_edges == NULL) {
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-hull.c
+++ libcairo-1.4.10/src/cairo-hull.c
@@ -62,7 +62,7 @@
     *extremum = vertices[0].point;
     vertices[0].point = tmp;
 
-    hull = malloc (num_vertices * sizeof (cairo_hull_t));
+    hull = _cairo_malloc_ab (num_vertices, sizeof (cairo_hull_t));
     if (hull == NULL)
 	return NULL;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-xlib-surface.c
+++ libcairo-1.4.10/src/cairo-xlib-surface.c
@@ -1579,7 +1579,7 @@
     mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE);
     solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);
 
-    offset_traps = malloc (sizeof (XTrapezoid) * num_traps);
+    offset_traps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid));
     if (!offset_traps)
 	return None;
 
@@ -1760,7 +1760,7 @@
 
 	n_boxes = pixman_region_num_rects (region);
 	if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
-	    rects = malloc (sizeof(XRectangle) * n_boxes);
+	    rects = _cairo_malloc_ab (n_boxes, sizeof(XRectangle));
 	    if (rects == NULL)
 		return CAIRO_STATUS_NO_MEMORY;
 	}else {
@@ -2815,7 +2815,7 @@
     if (num_elts <= STACK_ELTS_LEN) {
       elts = stack_elts;
     } else {
-      elts = malloc (num_elts * sizeof (XGlyphElt8));
+      elts = _cairo_malloc_ab (num_elts, sizeof (XGlyphElt8));
       if (elts == NULL)
 	  return CAIRO_STATUS_NO_MEMORY;
     }
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-pen.c
+++ libcairo-1.4.10/src/cairo-pen.c
@@ -78,7 +78,7 @@
 						    radius,
 						    ctm);
 
-    pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
+    pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
     if (pen->vertices == NULL) {
 	return CAIRO_STATUS_NO_MEMORY;
     }
@@ -119,7 +119,7 @@
     *pen = *other;
 
     if (pen->num_vertices) {
-	pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
+	pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
 	if (pen->vertices == NULL) {
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
@@ -138,7 +138,8 @@
     int i;
 
     num_vertices = pen->num_vertices + num_points;
-    vertices = realloc (pen->vertices, num_vertices * sizeof (cairo_pen_vertex_t));
+	vertices = _cairo_realloc_ab (pen->vertices,
+			num_vertices, sizeof (cairo_pen_vertex_t));
     if (vertices == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-quartz-surface.c
+++ libcairo-1.4.10/src/cairo-quartz-surface.c
@@ -1255,7 +1255,7 @@
 	float *fdash = sdash;
 	unsigned int k;
 	if (style->num_dashes > STATIC_DASH)
-	    fdash = malloc (sizeof(float)*style->num_dashes);
+	    fdash = _cairo_malloc_ab (style->num_dashes, sizeof (float));
 
 	for (k = 0; k < style->num_dashes; k++)
 	    fdash[k] = (float) style->dash[k];
@@ -1394,8 +1394,8 @@
     CGContextSetFontSize (surface->cgContext, 1.0);
 
     if (num_glyphs > STATIC_BUF_SIZE) {
-	cg_glyphs = (CGGlyph*) malloc(sizeof(CGGlyph) * num_glyphs);
-	cg_advances = (CGSize*) malloc(sizeof(CGSize) * num_glyphs);
+	cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof(CGGlyph));
+	cg_advances = (CGSize*) _cairo_malloc_ab (num_glyphs, sizeof(CGSize));
     }
 
     xprev = glyphs[0].x;
@@ -1711,7 +1711,7 @@
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
-    imageData = malloc (height * stride);
+    imageData = _cairo_malloc_ab (height, stride);
     if (!imageData) {
 	CGColorSpaceRelease (cgColorspace);
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-xcb-surface.c
+++ libcairo-1.4.10/src/cairo-xcb-surface.c
@@ -403,7 +403,7 @@
     bpp = _bits_per_pixel(surface->dpy, imagerep->depth);
     bytes_per_line = _bytes_per_line(surface->dpy, surface->width, bpp);
 
-    data = malloc (bytes_per_line * surface->height);
+    data = _cairo_malloc_ab (surface->height, bytes_per_line);
     if (data == NULL) {
 	free (imagerep);
 	return CAIRO_STATUS_NO_MEMORY;
@@ -1328,7 +1328,7 @@
     mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE);
     solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);
 
-    offset_traps = malloc (sizeof (xcb_render_trapezoid_t) * num_traps);
+    offset_traps = _cairo_malloc_ab (num_traps, sizeof (xcb_render_trapezoid_t));
     if (!offset_traps)
 	return XCB_NONE;
 
@@ -1515,7 +1515,7 @@
 
 	n_boxes = pixman_region_num_rects (region);
 	if (n_boxes > 0) {
-	    rects = malloc (sizeof(xcb_rectangle_t) * n_boxes);
+	    rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
 	    if (rects == NULL)
 		return CAIRO_STATUS_NO_MEMORY;
 	} else {
@@ -2360,7 +2360,7 @@
     /* We make a copy of the glyphs so that we can elide any size-zero
      * glyphs to workaround an X server bug, (present in at least Xorg
      * 7.1 without EXA). */
-    output_glyphs = malloc (num_glyphs * sizeof (cairo_glyph_t));
+    output_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
     if (output_glyphs == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-unicode.c
+++ libcairo-1.4.10/src/cairo-unicode.c
@@ -240,7 +240,7 @@
 	in = UTF8_NEXT_CHAR (in);
     }
 
-    str32 = malloc (sizeof (uint32_t) * (n_chars + 1));
+    str32 = _cairo_malloc_ab (n_chars + 1, sizeof (uint32_t));
     if (!str32)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -307,7 +307,7 @@
 	in = UTF8_NEXT_CHAR (in);
     }
 
-    str16 = malloc (sizeof (uint16_t) * (n16 + 1));
+    str16 = _cairo_malloc_ab (n16 + 1, sizeof (uint16_t));
     if (!str16)
 	return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-ps-surface.c
+++ libcairo-1.4.10/src/cairo-ps-surface.c
@@ -2037,7 +2037,7 @@
 	 * can modify some of the values.
 	 */
 	if (num_dashes % 2) {
-	    dash = malloc (2 * num_dashes * sizeof (double));
+	    dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
 	    if (dash == NULL)
 		return CAIRO_STATUS_NO_MEMORY;
 
@@ -2215,7 +2215,7 @@
     num_glyphs_unsigned = num_glyphs;
 
     _cairo_ps_surface_emit_pattern (surface, source);
-    glyph_ids = malloc (num_glyphs_unsigned*sizeof (cairo_ps_glyph_id_t));
+    glyph_ids = _cairo_malloc_ab (num_glyphs_unsigned, sizeof (cairo_ps_glyph_id_t));
     if (glyph_ids == NULL)
         return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-array.c
+++ libcairo-1.4.10/src/cairo-array.c
@@ -138,8 +138,9 @@
     }
 
     array->size = new_size;
-    new_elements = realloc (*array->elements,
-			    array->size * array->element_size);
+    new_elements = _cairo_realloc_ab (*array->elements,
+             array->size, array->element_size);
+
 
     if (new_elements == NULL) {
 	array->size = old_size;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-scaled-font.c
+++ libcairo-1.4.10/src/cairo-scaled-font.c
@@ -927,7 +927,7 @@
     if (status)
 	goto DONE;
 
-    *glyphs = (cairo_glyph_t *) malloc ((*num_glyphs) * (sizeof (cairo_glyph_t)));
+    *glyphs = (cairo_glyph_t *) _cairo_malloc_ab ((*num_glyphs), sizeof (cairo_glyph_t));
 
     if (*glyphs == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-spline.c
+++ libcairo-1.4.10/src/cairo-spline.c
@@ -109,11 +109,12 @@
     assert (spline->num_points <= spline->points_size);
 
     if (spline->points == spline->points_embedded) {
-	new_points = malloc (new_size * sizeof (cairo_point_t));
+	new_points = _cairo_malloc_ab (new_size, sizeof (cairo_point_t));
 	if (new_points)
 	    memcpy (new_points, spline->points, old_size * sizeof (cairo_point_t));
     } else {
-	new_points = realloc (spline->points, new_size * sizeof (cairo_point_t));
+		new_points = _cairo_realloc_ab (spline->points,
+				new_size, sizeof (cairo_point_t));
     }
 
     if (new_points == NULL) {
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-png.c
+++ libcairo-1.4.10/src/cairo-png.c
@@ -128,7 +128,7 @@
     else if (status != CAIRO_STATUS_SUCCESS)
 	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
 
-    rows = malloc (image->height * sizeof(png_byte*));
+    rows = _cairo_malloc_ab (image->height, sizeof(png_byte*));
     if (rows == NULL) {
         status = CAIRO_STATUS_NO_MEMORY;
 	goto BAIL1;
@@ -429,11 +429,11 @@
     png_read_update_info (png, info);
 
     pixel_size = 4;
-    data = malloc (png_width * png_height * pixel_size);
+    data = _cairo_malloc_abc (png_height, png_width, pixel_size);
     if (data == NULL)
 	goto BAIL;
 
-    row_pointers = malloc (png_height * sizeof(char *));
+    row_pointers = _cairo_malloc_ab (png_height, sizeof(char *));
     if (row_pointers == NULL)
 	goto BAIL;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-pdf-surface.c
+++ libcairo-1.4.10/src/cairo-pdf-surface.c
@@ -1262,7 +1262,7 @@
     color_function->id = 0;
     alpha_function->id = 0;
 
-    allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t));
+    allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t));
     if (allstops == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -2726,13 +2726,13 @@
     cairo_box_t font_bbox = {{0,0},{0,0}};
     cairo_box_t bbox = {{0,0},{0,0}};
 
-    glyphs = malloc (font_subset->num_glyphs * sizeof (cairo_pdf_resource_t));
+    glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t));
     if (glyphs == NULL) {
 	_cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
-    widths = malloc (font_subset->num_glyphs * sizeof (double));
+    widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double));
     if (widths == NULL) {
         free (glyphs);
 	_cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY);
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-scaled-font-subsets.c
+++ libcairo-1.4.10/src/cairo-scaled-font-subsets.c
@@ -390,7 +390,7 @@
 	subset.num_glyphs = collection->num_glyphs;
         /* No need to check for out of memory here. If to_unicode is NULL, the PDF
          * surface does not emit an ToUnicode stream */
-        subset.to_unicode = malloc (collection->num_glyphs*sizeof(unsigned long));
+        subset.to_unicode = _cairo_malloc_ab (collection->num_glyphs, sizeof (unsigned long));
         if (subset.to_unicode) {
             for (j = 0; j < collection->num_glyphs; j++) {
                 /* default unicode character required when mapping fails */
@@ -622,7 +622,7 @@
     if (! collection.glyphs_size)
 	return CAIRO_STATUS_SUCCESS;
 
-    collection.glyphs = malloc (collection.glyphs_size * sizeof(unsigned long));
+    collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
     if (collection.glyphs == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-win32-surface.c
+++ libcairo-1.4.10/src/cairo-win32-surface.c
@@ -186,7 +186,7 @@
     }
 
     if (num_palette > 2) {
-	bitmap_info = malloc (sizeof (BITMAPINFOHEADER) + num_palette * sizeof (RGBQUAD));
+	bitmap_info = _cairo_malloc_ab_plus_c (num_palette, sizeof(RGBQUAD), sizeof(BITMAPINFOHEADER));
 	if (!bitmap_info)
 	    return CAIRO_STATUS_NO_MEMORY;
     } else {
@@ -1546,8 +1546,8 @@
     SetBkMode(dst->dc, TRANSPARENT);
 
     if (num_glyphs > STACK_GLYPH_SIZE) {
-	glyph_buf = (WORD *)malloc(num_glyphs * sizeof(WORD));
-        dxy_buf = (int *)malloc(num_glyphs * 2 * sizeof(int));
+	glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD));
+        dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2);
     }
 
     /* It is vital that dx values for dxy_buf are calculated from the delta of
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-meta-surface.c
+++ libcairo-1.4.10/src/cairo-meta-surface.c
@@ -439,7 +439,7 @@
     if (status)
 	goto CLEANUP_COMMAND;
 
-    command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
+    command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
     if (command->glyphs == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto CLEANUP_SOURCE;
@@ -735,7 +735,7 @@
 	    int i, num_glyphs = command->show_glyphs.num_glyphs;
 
 	    if (has_device_transform) {
-		dev_glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
+		dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
 		if (dev_glyphs == NULL) {
 		    status = CAIRO_STATUS_NO_MEMORY;
 		    break;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-directfb-surface.c
+++ libcairo-1.4.10/src/cairo-directfb-surface.c
@@ -1113,7 +1113,7 @@
             if( surface->clips )
                 free (surface->clips);
             
-            surface->clips = malloc (n_boxes * sizeof(DFBRegion));
+            surface->clips = _cairo_malloc_ab (n_boxes, sizeof(DFBRegion));
             if (!surface->clips) {
                 surface->n_clips = 0;
                 return CAIRO_STATUS_NO_MEMORY;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-glitz-surface.c
+++ libcairo-1.4.10/src/cairo-glitz-surface.c
@@ -197,7 +197,7 @@
     pf.bytes_per_line = (((width * format.bpp) / 8) + 3) & -4;
     pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
 
-    pixels = malloc (height * pf.bytes_per_line);
+    pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
     if (!pixels)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -627,8 +627,22 @@
 
 	n_params = gradient->n_stops * 3 + n_base_params;
 
-	data = malloc (sizeof (glitz_fixed16_16_t) * n_params +
-		       sizeof (unsigned int) * gradient->n_stops);
+        /* check for int overflow */
+        {
+            int size1, size2;
+            if (n_params >= INT32_MAX / sizeof (glitz_fixed16_16_t) ||
+                gradient->n_stops >= INT32_MAX / sizeof (unsigned int))
+                return CAIRO_STATUS_NO_MEMORY;
+
+            size1 = n_params * sizeof (glitz_fixed16_16_t);
+            size2 = gradient->n_stops * sizeof (unsigned int);
+
+            if (size1 >= INT32_MAX - size2)
+                return CAIRO_STATUS_NO_MEMORY;
+
+            data = malloc (size1 + size2);
+        }
+
 	if (!data)
 	    return CAIRO_STATUS_NO_MEMORY;
 
@@ -1992,9 +2006,19 @@
     if (num_glyphs > N_STACK_BUF)
     {
 	char *data;
+        int size1, size2;
+
+        if (num_glyphs >= INT32_MAX / sizeof(void*) ||
+            num_glyphs >= INT32_MAX / sizeof(glitz_float_t) ||
+            (num_glyphs * sizeof(glitz_float_t)) >= INT32_MAX / 16)
+            goto FAIL1;
+
+        size1 = num_glyphs * sizeof(void *);
+        size2 = num_glyphs * sizeof(glitz_float_t) * 16;
+        if (size1 >= INT32_MAX - size2)
+            goto FAIL1;
 
-	data = malloc (num_glyphs * sizeof (void *) +
-		       num_glyphs * sizeof (glitz_float_t) * 16);
+	data = malloc (size1 + size2);
 	if (!data)
 	    goto FAIL1;
 
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-path-stroke.c
+++ libcairo-1.4.10/src/cairo-path-stroke.c
@@ -1076,7 +1076,8 @@
 	/* Common case is one rectangle of exactly 4 segments. */
 	if (new_size == 0)
 	    new_size = 4;
-	new_segments = realloc (stroker->segments, new_size * sizeof (cairo_line_t));
+	new_segments = _cairo_realloc_ab (stroker->segments,
+	                          new_size, sizeof (cairo_line_t));
 	if (new_segments == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
 	stroker->segments_size = new_size;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-surface-fallback.c
+++ libcairo-1.4.10/src/cairo-surface-fallback.c
@@ -1166,7 +1166,7 @@
     /* If the fetched image isn't at 0,0, we need to offset the rectangles */
 
     if (state.image_rect.x != 0 || state.image_rect.y != 0) {
-	offset_rects = malloc (sizeof (cairo_rectangle_int16_t) * num_rects);
+      offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int16_t));
 	if (offset_rects == NULL) {
 	    status = CAIRO_STATUS_NO_MEMORY;
 	    goto DONE;
@@ -1222,7 +1222,7 @@
     /* If the destination image isn't at 0,0, we need to offset the trapezoids */
 
     if (state.image_rect.x != 0 || state.image_rect.y != 0) {
-	offset_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
+	offset_traps = _cairo_malloc_ab (num_traps, sizeof (cairo_trapezoid_t));
 	if (!offset_traps) {
 	    status = CAIRO_STATUS_NO_MEMORY;
 	    goto DONE;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairoint.h
+++ libcairo-1.4.10/src/cairoint.h
@@ -181,6 +181,7 @@
 
 #include "cairo-mutex-private.h"
 #include "cairo-wideint-private.h"
+#include "cairo-malloc-private.h"
 
 typedef int32_t		cairo_fixed_16_16_t;
 typedef cairo_int64_t	cairo_fixed_32_32_t;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-win32-font.c
+++ libcairo-1.4.10/src/cairo-win32-font.c
@@ -613,8 +613,8 @@
 	    dx = NULL;
 	}
 
-	glyph_indices = malloc (sizeof (WCHAR) * buffer_size);
-	dx = malloc (sizeof (int) * buffer_size);
+	glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR));
+	dx = _cairo_malloc_ab (buffer_size, sizeof (int));
 	if (!glyph_indices || !dx) {
 	    status = CAIRO_STATUS_NO_MEMORY;
 	    goto FAIL2;
@@ -645,7 +645,7 @@
     }
 
     *num_glyphs = gcp_results.nGlyphs;
-    *glyphs = malloc (sizeof (cairo_glyph_t) * gcp_results.nGlyphs);
+    *glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t));
     if (!*glyphs) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto FAIL2;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/src/cairo-path.c
+++ libcairo-1.4.10/src/cairo-path.c
@@ -381,7 +381,7 @@
 	return (cairo_path_t*) &_cairo_path_nil;
     }
 
-    path->data = malloc (path->num_data * sizeof (cairo_path_data_t));
+    path->data = _cairo_malloc_ab (path->num_data, sizeof (cairo_path_data_t));
     if (path->data == NULL) {
 	free (path);
 	return (cairo_path_t*) &_cairo_path_nil;
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/pixman/src/fbcompose.c
+++ libcairo-1.4.10/pixman/src/fbcompose.c
@@ -3883,7 +3883,7 @@
     }
 
     if (width > SCANLINE_BUFFER_LENGTH)
-        alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
+        alpha_buffer = (CARD32 *) _pixman_malloc_ab (width, sizeof(CARD32));
 
     fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
     fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
@@ -4286,7 +4286,7 @@
     compose_data.mask = pMask;
     compose_data.dest = pDst;
     if (width > SCANLINE_BUFFER_LENGTH)
-        scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
+	scanline_buffer = (CARD32 *) _pixman_malloc_abc (width, 3, sizeof(CARD32));
 
     n = pixman_region_num_rects (&region);
     pbox = pixman_region_rects (&region);
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/pixman/src/pixmanint.h
+++ libcairo-1.4.10/pixman/src/pixmanint.h
@@ -1073,4 +1073,21 @@
 		       (*((a)+2) = (CARD8) ((v) >> 16))))
 #endif
 
+
+/* Allocation helpers */
+
+#define _pixman_malloc_ab(n, size) \
+  ((unsigned) (n) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   malloc((unsigned) (n) * (unsigned) (size)))
+
+#define _pixman_malloc_abc(a, b, size) \
+  ((unsigned) (a) >= INT32_MAX / (unsigned) (b) ? NULL : \
+   (unsigned) ((a)*(b)) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   malloc((unsigned) (a) * (unsigned) (b) * (unsigned) size))
+
+#define _pixman_malloc_ab_plus_c(n, size, k) \
+  ((unsigned) (n) >= INT32_MAX / (unsigned) (size) ? NULL : \
+   (unsigned) (k) >= INT32_MAX - (unsigned) (n) * (unsigned) (size) ? NULL : \
+   malloc((unsigned) (n) * (unsigned) (size) + (unsigned) (k)))
+
 #endif /* _PIXMANINT_H_ */
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/pixman/src/pixman.h
+++ libcairo-1.4.10/pixman/src/pixman.h
@@ -89,6 +89,13 @@
   typedef unsigned __int32 uint32_t;
   typedef __int64 int64_t;
   typedef unsigned __int64 uint64_t;
+
+# ifndef UINT16_MAX
+#  define UINT16_MAX	(65535)
+# endif
+# ifndef UINT32_MAX
+#  define UINT32_MAX	(0xffffffffU)
+# endif
 #else
 #error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
 #endif
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/pixman/src/pixregion.c
+++ libcairo-1.4.10/pixman/src/pixregion.c
@@ -148,7 +148,31 @@
         ((r1)->y1 <= (r2)->y1) && \
         ((r1)->y2 >= (r2)->y2) )
 
-#define allocData(n) malloc(PIXREGION_SZOF(n))
+static size_t
+PIXREGION_SZOF(size_t n)
+{
+    size_t size = n * sizeof(pixman_box16_t);
+    if (n > UINT32_MAX / sizeof(pixman_box16_t))
+	return 0;
+
+    if (sizeof(pixman_region16_data_t) > UINT32_MAX - size)
+	return 0;
+
+    return size + sizeof(pixman_region16_data_t);
+}
+
+static void
+allocData(size_t n, void **data)
+{
+    size_t sz = PIXREGION_SZOF(n);
+    if (!sz) {
+	*data = NULL;
+	return;
+    }
+
+    *data = malloc(sz);
+}
+
 #define freeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
 
 #define RECTALLOC_BAIL(pReg,n,bail) \
@@ -185,7 +209,10 @@
 if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
 {									 \
     pixman_region16_data_t * NewData;							 \
-    NewData = (pixman_region16_data_t *)realloc((reg)->data, PIXREGION_SZOF(numRects));	 \
+    size_t data_size = PIXREGION_SZOF(numRects);			 \
+    if (!data_size)							 \
+      goto bail;							 \
+    NewData = (pixman_region16_data_t *)realloc((reg)->data, data_size); \
     if (NewData)							 \
     {									 \
 	NewData->size = (numRects);					 \
@@ -372,11 +399,12 @@
 pixman_rect_alloc(pixman_region16_t * region, int n)
 {
     pixman_region16_data_t *data;
+    size_t data_size;
 
     if (!region->data)
     {
 	n++;
-	region->data = allocData(n);
+	allocData(n, (void **) &region->data);
 	if (!region->data)
 	    return pixman_break (region);
 	region->data->numRects = 1;
@@ -384,7 +412,7 @@
     }
     else if (!region->data->size)
     {
-	region->data = allocData(n);
+      allocData(n, (void **) &region->data);
 	if (!region->data)
 	    return pixman_break (region);
 	region->data->numRects = 0;
@@ -398,7 +426,10 @@
 		n = 250;
 	}
 	n += region->data->numRects;
-	data = (pixman_region16_data_t *)realloc(region->data, PIXREGION_SZOF(n));
+	data_size = PIXREGION_SZOF(n);
+	if (!data_size)
+	    return pixman_break (region);
+	data = (pixman_region16_data_t *)realloc(region->data, data_size);
 	if (!data)
 	    return pixman_break (region);
 	region->data = data;
@@ -424,7 +455,7 @@
     if (!dst->data || (dst->data->size < src->data->numRects))
     {
 	freeData(dst);
-	dst->data = allocData(src->data->numRects);
+	allocData(src->data->numRects, (void **) &dst->data);
 	if (!dst->data)
 	    return pixman_break (dst);
 	dst->data->size = src->data->numRects;
@@ -835,8 +866,10 @@
 	AppendRegions(newReg, r2BandEnd, r2End);
     }
 
-    if (oldData)
+    if (oldData) {
 	free(oldData);
+	oldData = NULL;
+    }
 
     if (!(numRects = newReg->data->numRects))
     {
@@ -1493,7 +1526,7 @@
 
     /* Set up the first region to be the first rectangle in badreg */
     /* Note that step 2 code will never overflow the ri[0].reg rects array */
-    ri = (RegionInfo *) malloc(4 * sizeof(RegionInfo));
+    ri = (RegionInfo *) _pixman_malloc_ab(4, sizeof(RegionInfo));
     if (!ri)
 	return pixman_break (badreg);
     sizeRI = 4;
@@ -1555,9 +1588,13 @@
 	/* Uh-oh.  No regions were appropriate.  Create a new one. */
 	if (sizeRI == numRI)
 	{
+	    size_t data_size;
 	    /* Oops, allocate space for new region information */
 	    sizeRI <<= 1;
-	    rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo));
+	    data_size = sizeRI * sizeof(RegionInfo);
+	    if (data_size / sizeRI != sizeof(RegionInfo))
+		goto bail;
+	    rit = (RegionInfo *) realloc(ri, data_size);
 	    if (!rit)
 		goto bail;
 	    ri = rit;
@@ -1659,7 +1696,7 @@
 	}
 	return region;
     }
-    pData = allocData(nrects);
+    allocData(nrects, &pData);
     if (!pData)
     {
 	pixman_break (region);
@@ -2167,7 +2204,7 @@
     if (!dst->data || (dst->data->size < src->data->numRects))
     {
 	freeData(dst);
-	dst->data = allocData(src->data->numRects);
+	allocData(src->data->numRects, &dst->data);
 	if (!dst->data)
 	    return pixman_break (dst);
     }
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/pixman/src/icimage.c
+++ libcairo-1.4.10/pixman/src/icimage.c
@@ -215,8 +215,8 @@
     if (!image)
 	return NULL;
 
-    linear = malloc (sizeof (pixman_linear_gradient_image_t) +
-		     sizeof (pixman_gradient_stop_t) * n_stops);
+    linear = _pixman_malloc_ab_plus_c (n_stops, sizeof (pixman_gradient_stop_t),
+			       sizeof (pixman_linear_gradient_image_t));
     if (!linear)
     {
 	free (image);
@@ -259,8 +259,8 @@
     if (!image)
 	return NULL;
 
-    radial = malloc (sizeof (pixman_radial_gradient_image_t) +
-		     sizeof (pixman_gradient_stop_t) * n_stops);
+    radial = _pixman_malloc_ab_plus_c (n_stops, sizeof (pixman_gradient_stop_t),
+			       sizeof (pixman_radial_gradient_image_t));
     if (!radial)
     {
 	free (image);
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/pixman/src/pixregionint.h
+++ libcairo-1.4.10/pixman/src/pixregionint.h
@@ -70,6 +70,5 @@
 #define PIXREGION_BOX(reg,i) (&PIXREGION_BOXPTR(reg)[i])
 #define PIXREGION_TOP(reg) PIXREGION_BOX(reg, (reg)->data->numRects)
 #define PIXREGION_END(reg) PIXREGION_BOX(reg, (reg)->data->numRects - 1)
-#define PIXREGION_SZOF(n) (sizeof(pixman_region16_data_t) + ((n) * sizeof(pixman_box16_t)))
 
 #endif /* _PIXREGIONINT_H_ */
only in patch2:
unchanged:
--- libcairo-1.4.10.orig/CODING_STYLE
+++ libcairo-1.4.10/CODING_STYLE
@@ -243,3 +243,28 @@
 this. If it's not available due to additional nesting above which
 require some cleanup after the current block, then consider splitting
 the current block into a new function before using goto.
+
+Memory allocation
+-----------------
+
+Because much of cairo's data consists of dynamically allocated arrays,
+it's very easy to introduce integer overflow issues whenever malloc()
+is called.  Use the _cairo_malloc2(), _cairo_malloc3(), and
+_cairo_malloc2_add1 macros to avoid these cases; these macros check
+for overflow and will return NULL in that case.
+
+  malloc (n * size) => _cairo_malloc_ab (n, size)
+    e.g. malloc (num_elts * sizeof(some_type)) =>
+         _cairo_malloc2 (num_elts, sizeof(some_type))
+
+  malloc (a * b * size) => _cairo_malloc_abc (a, b, size)
+    e.g. malloc (width * height * 4) =>
+         _cairo_malloc3 (width, height, 4)
+
+  malloc (n * size + k) => _cairo_malloc_ab_plus_c (n, size, k)
+    e.g. malloc (num * sizeof(entry) + sizeof(header)) =>
+         _cairo_malloc2k (num, sizeof(entry), sizeof(header))
+
+In general, be wary of performing any arithmetic operations in an
+argument to malloc.  You should explicitly check for integer overflow
+yourself in any more complex situations.
\ No newline at end of file
