1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* Cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2007 Mozilla Corporation
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is Mozilla Foundation
32
 *
33
 * Contributor(s):
34
 *	Vladimir Vukicevic <vladimir@pobox.com>
35
 */
36

            
37
#ifndef CAIRO_MALLOC_PRIVATE_H
38
#define CAIRO_MALLOC_PRIVATE_H
39

            
40
#include "cairo-wideint-private.h"
41
#include <stdlib.h>
42

            
43
#if HAVE_MEMFAULT
44
#include <memfault.h>
45
#define CAIRO_INJECT_FAULT() MEMFAULT_INJECT_FAULT()
46
#else
47
#define CAIRO_INJECT_FAULT() 0
48
#endif
49

            
50
/**
51
 * _cairo_malloc:
52
 * @size: size in bytes
53
 *
54
 * Allocate @size memory using malloc().
55
 * The memory should be freed using free().
56
 * malloc is skipped, if 0 bytes are requested, and %NULL will be returned.
57
 *
58
 * Return value: A pointer to the newly allocated memory, or %NULL in
59
 * case of malloc() failure or size is 0.
60
 **/
61

            
62
#define _cairo_malloc(size) \
63
   ((size) != 0 ? malloc(size) : NULL)
64

            
65
/**
66
 * _cairo_calloc:
67
 * @size: size of each element
68
 *
69
 * Allocates @size memory using calloc(). Behaves much like
70
 * calloc(), except that only one parameter is required.
71
 * The memory should be freed using free().
72
 * calloc is skipped, if 0 bytes are requested, and %NULL will be returned.
73
 *
74
 * Return value: A pointer to the newly allocated memory, or %NULL in
75
 * case of calloc() failure or overflow.
76
 **/
77

            
78
#define _cairo_calloc(size) \
79
    ((size) != 0 ? calloc(1,size) : NULL)
80

            
81
/**
82
 * _cairo_malloc_ab:
83
 * @a: number of elements to allocate
84
 * @size: size of each element
85
 *
86
 * Allocates @a*@size memory using _cairo_malloc(), taking care to not
87
 * overflow when doing the multiplication.  Behaves much like
88
 * calloc(), except that the returned memory is not set to zero.
89
 * The memory should be freed using free().
90
 *
91
 * @size should be a constant so that the compiler can optimize
92
 * out a constant division.
93
 *
94
 * Return value: A pointer to the newly allocated memory, or %NULL in
95
 * case of malloc() failure or overflow.
96
 **/
97

            
98
static cairo_always_inline void *
99
_cairo_malloc_ab(size_t a, size_t size)
100
{
101
    size_t c;
102
158149
    if (_cairo_mul_size_t_overflow (a, size, &c))
103
	return NULL;
104

            
105
158149
    return _cairo_malloc(c);
106
}
107

            
108
/**
109
 * _cairo_calloc_ab:
110
 * @a: number of elements to allocate
111
 * @size: size of each element
112
 *
113
 * Allocates @a*@size memory using _cairo_calloc(), taking care to not
114
 * overflow when doing the multiplication.
115
 *
116
 * @size should be a constant so that the compiler can optimize
117
 * out a constant division.
118
 *
119
 * Return value: A pointer to the newly allocated memory, or %NULL in
120
 * case of calloc() failure or overflow.
121
 **/
122

            
123
static cairo_always_inline void *
124
_cairo_calloc_ab(size_t a, size_t size)
125
{
126
    size_t c;
127
5512
    if (_cairo_mul_size_t_overflow (a, size, &c))
128
	return NULL;
129

            
130
5512
    return _cairo_calloc(c);
131
}
132

            
133
/**
134
 * _cairo_realloc_ab:
135
 * @ptr: original pointer to block of memory to be resized
136
 * @a: number of elements to allocate
137
 * @size: size of each element
138
 *
139
 * Reallocates @ptr a block of @a*@size memory using realloc(), taking
140
 * care to not overflow when doing the multiplication.  The memory
141
 * should be freed using free().
142
 *
143
 * @size should be a constant so that the compiler can optimize
144
 * out a constant division.
145
 *
146
 * Return value: A pointer to the newly allocated memory, or %NULL in
147
 * case of realloc() failure or overflow (whereupon the original block
148
 * of memory * is left untouched).
149
 **/
150

            
151
static cairo_always_inline void *
152
_cairo_realloc_ab(void *ptr, size_t a, size_t size)
153
{
154
    size_t c;
155
139030
    if (_cairo_mul_size_t_overflow (a, size, &c))
156
	return NULL;
157

            
158
139030
    return realloc(ptr, c);
159
}
160

            
161
/**
162
 * _cairo_malloc_abc:
163
 * @a: first factor of number of elements to allocate
164
 * @b: second factor of number of elements to allocate
165
 * @size: size of each element
166
 *
167
 * Allocates @a*@b*@size memory using _cairo_malloc(), taking care to not
168
 * overflow when doing the multiplication.  Behaves like
169
 * _cairo_malloc_ab().  The memory should be freed using free().
170
 *
171
 * @size should be a constant so that the compiler can optimize
172
 * out a constant division.
173
 *
174
 * Return value: A pointer to the newly allocated memory, or %NULL in
175
 * case of malloc() failure or overflow.
176
 **/
177

            
178
static cairo_always_inline void *
179
_cairo_malloc_abc(size_t a, size_t b, size_t size)
180
{
181
    size_t c, d;
182
7
    if (_cairo_mul_size_t_overflow (a, b, &c))
183
	return NULL;
184

            
185
7
    if (_cairo_mul_size_t_overflow (c, size, &d))
186
	return NULL;
187

            
188
7
    return _cairo_malloc(d);
189
}
190

            
191
/**
192
 * _cairo_malloc_ab_plus_c:
193
 * @a: number of elements to allocate
194
 * @size: size of each element
195
 * @c: additional size to allocate
196
 *
197
 * Allocates @a*@size+@c memory using _cairo_malloc(), taking care to not
198
 * overflow when doing the arithmetic.  Behaves similar to
199
 * _cairo_malloc_ab().  The memory should be freed using free().
200
 *
201
 * Return value: A pointer to the newly allocated memory, or %NULL in
202
 * case of malloc() failure or overflow.
203
 **/
204

            
205
static cairo_always_inline void *
206
_cairo_malloc_ab_plus_c(size_t a, size_t size, size_t c)
207
{
208
    size_t d, e;
209
520473
    if (_cairo_mul_size_t_overflow (a, size, &d))
210
	return NULL;
211

            
212
520473
    if (_cairo_add_size_t_overflow (d, c, &e))
213
	return NULL;
214

            
215
520473
    return _cairo_malloc(e);
216
}
217

            
218
#endif /* CAIRO_MALLOC_PRIVATE_H */