diff options
author | Vladimir Vukicevic <vladimir@pobox.com> | 2007-06-19 13:15:21 -0700 |
---|---|---|
committer | Vladimir Vukicevic <vladimir@feisty.(none)> | 2007-06-29 09:46:08 -0700 |
commit | 5c7d2d14d78e4dfb1ef6d2c40f0910f177e07360 (patch) | |
tree | bb1abcb2f1144059d4444d8db343014e07791593 | |
parent | fc34073464c487405b6e2e0a5fa269a1ae15a02a (diff) |
[fix] Avoid int overflow when allocating large buffers
This patch introduces three macros: _cairo_malloc_ab,
_cairo_malloc_abc, _cairo_malloc_ab_plus_c and replaces various calls
to malloc(a*b), malloc(a*b*c), and malloc(a*b+c) with them. The macros
return NULL if int overflow would occur during the allocation. See
CODING_STYLE for more information.
41 files changed, 308 insertions, 89 deletions
diff --git a/CODING_STYLE b/CODING_STYLE index 2aef41c9..73fe2a9b 100644 --- a/CODING_STYLE +++ b/CODING_STYLE @@ -243,3 +243,28 @@ The return statement is often the best thing to use in a pattern like 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 diff --git a/pixman/src/fbcompose.c b/pixman/src/fbcompose.c index 4197e344..e2823ec3 100644 --- a/pixman/src/fbcompose.c +++ b/pixman/src/fbcompose.c @@ -3883,7 +3883,7 @@ static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD3 } 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 @@ pixman_compositeGeneral (pixman_operator_t op, 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 (®ion); pbox = pixman_region_rects (®ion); diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c index 61a84c5c..8bcccc48 100644 --- a/pixman/src/icimage.c +++ b/pixman/src/icimage.c @@ -215,8 +215,8 @@ pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient, 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 @@ pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient, 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); diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h index feaf60ae..491fc893 100644 --- a/pixman/src/pixman.h +++ b/pixman/src/pixman.h @@ -89,6 +89,13 @@ SOFTWARE. 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 diff --git a/pixman/src/pixmanint.h b/pixman/src/pixmanint.h index a10a8342..6ad373eb 100644 --- a/pixman/src/pixmanint.h +++ b/pixman/src/pixmanint.h @@ -1073,4 +1073,21 @@ typedef xFixed_16_16 xFixed; (*((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_ */ diff --git a/pixman/src/pixregion.c b/pixman/src/pixregion.c index 4cd08e59..1ed3ad70 100644 --- a/pixman/src/pixregion.c +++ b/pixman/src/pixregion.c @@ -148,7 +148,31 @@ pixman_rect_alloc(pixman_region16_t * region, int n); ((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 (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \ 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 @@ static pixman_region_status_t 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 **) ®ion->data); if (!region->data) return pixman_break (region); region->data->numRects = 1; @@ -384,7 +412,7 @@ pixman_rect_alloc(pixman_region16_t * region, int n) } else if (!region->data->size) { - region->data = allocData(n); + allocData(n, (void **) ®ion->data); if (!region->data) return pixman_break (region); region->data->numRects = 0; @@ -398,7 +426,10 @@ pixman_rect_alloc(pixman_region16_t * region, int n) 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 @@ pixman_region_copy(pixman_region16_t *dst, pixman_region16_t *src) 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 @@ pixman_op( AppendRegions(newReg, r2BandEnd, r2End); } - if (oldData) + if (oldData) { free(oldData); + oldData = NULL; + } if (!(numRects = newReg->data->numRects)) { @@ -1493,7 +1526,7 @@ pixman_region_validate(pixman_region16_t * badreg, /* 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 @@ pixman_region_validate(pixman_region16_t * badreg, /* 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 @@ pixman_region_rectsToRegion(nrects, prect, ctype) } return region; } - pData = allocData(nrects); + allocData(nrects, &pData); if (!pData) { pixman_break (region); @@ -2167,7 +2204,7 @@ pixman_region16_data_copy(pixman_region16_t * dst, pixman_region16_t * src) 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); } diff --git a/pixman/src/pixregionint.h b/pixman/src/pixregionint.h index 385a7f23..0ac7db42 100644 --- a/pixman/src/pixregionint.h +++ b/pixman/src/pixregionint.h @@ -70,6 +70,5 @@ typedef struct pixman_region16_point { #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_ */ diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c index 361e787e..d1196f0e 100644 --- a/src/cairo-atsui-font.c +++ b/src/cairo-atsui-font.c @@ -809,7 +809,7 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font, *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; } diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c index b8d97fa2..267459c9 100644 --- a/src/cairo-bentley-ottmann.c +++ b/src/cairo-bentley-ottmann.c @@ -754,7 +754,7 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, * 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 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, 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 @@ run_test (const char *test_name, 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); diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp index abf094a1..193fa43f 100644 --- a/src/cairo-beos-surface.cpp +++ b/src/cairo-beos-surface.cpp @@ -259,7 +259,7 @@ premultiply_rgba (unsigned char* data, 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 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap) 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); } diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 60f2418f..83940774 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -634,9 +634,13 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) 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; diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index fa31b063..5505501b 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -1113,7 +1113,7 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, 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; diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 89bb12a4..4dc61eea 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -742,7 +742,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap, 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 @@ _get_bitmap_surface (FT_Bitmap *bitmap, 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; diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index ab154042..de91fc72 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -197,7 +197,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, 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 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern, 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 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, 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; diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index fc8c5456..901fa586 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -530,7 +530,7 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash 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 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, 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 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, 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; diff --git a/src/cairo-hull.c b/src/cairo-hull.c index e9d0a155..c56e9e05 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -62,7 +62,7 @@ _cairo_hull_create (cairo_pen_vertex_t *vertices, int num_vertices) *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; diff --git a/src/cairo-malloc-private.h b/src/cairo-malloc-private.h new file mode 100644 index 00000000..f503b395 --- /dev/null +++ b/src/cairo-malloc-private.h @@ -0,0 +1,104 @@ +/* -*- 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 @a*@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_malloc_abc: + * @a: first factor of number of elements to allocate + * @b: second factor of number of elements to allocate + * @size: size of each element + * + * Allocates @a*@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 @a*@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 */ diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 8dbd6084..30a64e72 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -439,7 +439,7 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface, 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 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, 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; diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c index 319a7aba..1535de4d 100644 --- a/src/cairo-os2-surface.c +++ b/src/cairo-os2-surface.c @@ -296,8 +296,9 @@ _cairo_os2_surface_blit_pixels (cairo_os2_surface_t *surface, 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 @@ cairo_os2_surface_create (HPS hps_client_window, 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 @@ cairo_os2_surface_set_size (cairo_surface_t *surface, } /* 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! diff --git a/src/cairo-path.c b/src/cairo-path.c index 4c8e09e1..0740ebc4 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -381,7 +381,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, 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; diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 9fafc991..6ead4b2f 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -133,8 +133,8 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, 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,7 +757,7 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern) 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 { diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 1e73c4c4..dc5cda5b 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1262,7 +1262,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, 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_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, 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); diff --git a/src/cairo-pen.c b/src/cairo-pen.c index ec9eb7ac..9392322d 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -78,7 +78,7 @@ _cairo_pen_init (cairo_pen_t *pen, 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 @@ _cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other) *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; } diff --git a/src/cairo-png.c b/src/cairo-png.c index 35db3d9a..761fb3f3 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -128,7 +128,7 @@ write_png (cairo_surface_t *surface, 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 @@ read_png (png_rw_ptr read_func, 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; diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index e9fc78b7..726884a9 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -93,7 +93,7 @@ _cairo_polygon_grow (cairo_polygon_t *polygon) 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 { diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 919a498c..2da20d46 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -2037,7 +2037,7 @@ _cairo_ps_surface_stroke (void *abstract_surface, * 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 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, 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; diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index 06c8ba8c..b63b139f 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -1255,7 +1255,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface, 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 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, 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 @@ cairo_quartz_surface_create (cairo_format_t format, 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); diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index 65b1cdce..ea2e63ae 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -390,7 +390,7 @@ _cairo_sub_font_collect (void *entry, void *closure) 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 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t 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; diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 7a472191..ef70a389 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -927,7 +927,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, 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; diff --git a/src/cairo-spline.c b/src/cairo-spline.c index bf877700..db748b30 100644 --- a/src/cairo-spline.c +++ b/src/cairo-spline.c @@ -109,7 +109,7 @@ _cairo_spline_grow (cairo_spline_t *spline) 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 { diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c index a1509064..2eccb80d 100644 --- a/src/cairo-stroke-style.c +++ b/src/cairo-stroke-style.c @@ -62,7 +62,7 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style, 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; diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 8898aee1..bf7ae995 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -1166,7 +1166,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface, /* 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 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, /* 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; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index d7ef33f1..447cb62e 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1245,7 +1245,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface, 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; } diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index 483440ff..9d5ed6a3 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -1220,7 +1220,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output, 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) { diff --git a/src/cairo-traps.c b/src/cairo-traps.c index dd885c54..78e65ab4 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -260,7 +260,7 @@ _cairo_traps_grow (cairo_traps_t *traps) 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 { diff --git a/src/cairo-unicode.c b/src/cairo-unicode.c index 9abb0ebc..1d1c00a9 100644 --- a/src/cairo-unicode.c +++ b/src/cairo-unicode.c @@ -240,7 +240,7 @@ _cairo_utf8_to_ucs4 (const unsigned char *str, 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 @@ _cairo_utf8_to_utf16 (const unsigned char *str, 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; diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index e1f263b6..681dba77 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -613,8 +613,8 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font, 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 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font, } *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; diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 450887a1..7f86eb8c 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -186,7 +186,7 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface, } 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 @@ _cairo_win32_surface_show_glyphs (void *surface, 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 diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index f9290409..f16de3f7 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -403,7 +403,7 @@ _get_image_surface (cairo_xcb_surface_t *surface, 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 @@ _create_trapezoid_mask (cairo_xcb_surface_t *dst, 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 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface, 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 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, /* 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; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 39175bdf..3e771655 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -1579,7 +1579,7 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst, 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 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, 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 @@ _cairo_xlib_surface_emit_glyphs_chunk (cairo_xlib_surface_t *dst, 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; } diff --git a/src/cairoint.h b/src/cairoint.h index 07846b83..21d43d92 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -181,6 +181,7 @@ do { \ #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; |