Mercurial > hg > sv-dependency-builds
comparison src/flac-1.2.1/include/share/alloc.h @ 1:05aa0afa9217
Bring in flac, ogg, vorbis
author | Chris Cannam |
---|---|
date | Tue, 19 Mar 2013 17:37:49 +0000 |
parents | |
children | e13257ea84a4 |
comparison
equal
deleted
inserted
replaced
0:c7265573341e | 1:05aa0afa9217 |
---|---|
1 /* alloc - Convenience routines for safely allocating memory | |
2 * Copyright (C) 2007 Josh Coalson | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Lesser General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2.1 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Lesser General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Lesser General Public | |
15 * License along with this library; if not, write to the Free Software | |
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
17 */ | |
18 | |
19 #ifndef FLAC__SHARE__ALLOC_H | |
20 #define FLAC__SHARE__ALLOC_H | |
21 | |
22 #if HAVE_CONFIG_H | |
23 # include <config.h> | |
24 #endif | |
25 | |
26 /* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early | |
27 * before #including this file, otherwise SIZE_MAX might not be defined | |
28 */ | |
29 | |
30 #include <limits.h> /* for SIZE_MAX */ | |
31 #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ | |
32 #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ | |
33 #endif | |
34 #include <stdlib.h> /* for size_t, malloc(), etc */ | |
35 | |
36 #ifndef SIZE_MAX | |
37 # ifndef SIZE_T_MAX | |
38 # ifdef _MSC_VER | |
39 # define SIZE_T_MAX UINT_MAX | |
40 # else | |
41 # error | |
42 # endif | |
43 # endif | |
44 # define SIZE_MAX SIZE_T_MAX | |
45 #endif | |
46 | |
47 #ifndef FLaC__INLINE | |
48 #define FLaC__INLINE | |
49 #endif | |
50 | |
51 /* avoid malloc()ing 0 bytes, see: | |
52 * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 | |
53 */ | |
54 static FLaC__INLINE void *safe_malloc_(size_t size) | |
55 { | |
56 /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |
57 if(!size) | |
58 size++; | |
59 return malloc(size); | |
60 } | |
61 | |
62 static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size) | |
63 { | |
64 if(!nmemb || !size) | |
65 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |
66 return calloc(nmemb, size); | |
67 } | |
68 | |
69 /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ | |
70 | |
71 static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2) | |
72 { | |
73 size2 += size1; | |
74 if(size2 < size1) | |
75 return 0; | |
76 return safe_malloc_(size2); | |
77 } | |
78 | |
79 static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) | |
80 { | |
81 size2 += size1; | |
82 if(size2 < size1) | |
83 return 0; | |
84 size3 += size2; | |
85 if(size3 < size2) | |
86 return 0; | |
87 return safe_malloc_(size3); | |
88 } | |
89 | |
90 static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) | |
91 { | |
92 size2 += size1; | |
93 if(size2 < size1) | |
94 return 0; | |
95 size3 += size2; | |
96 if(size3 < size2) | |
97 return 0; | |
98 size4 += size3; | |
99 if(size4 < size3) | |
100 return 0; | |
101 return safe_malloc_(size4); | |
102 } | |
103 | |
104 static FLaC__INLINE void *safe_malloc_mul_2op_(size_t size1, size_t size2) | |
105 #if 0 | |
106 needs support for cases where sizeof(size_t) != 4 | |
107 { | |
108 /* could be faster #ifdef'ing off SIZEOF_SIZE_T */ | |
109 if(sizeof(size_t) == 4) { | |
110 if ((double)size1 * (double)size2 < 4294967296.0) | |
111 return malloc(size1*size2); | |
112 } | |
113 return 0; | |
114 } | |
115 #else | |
116 /* better? */ | |
117 { | |
118 if(!size1 || !size2) | |
119 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |
120 if(size1 > SIZE_MAX / size2) | |
121 return 0; | |
122 return malloc(size1*size2); | |
123 } | |
124 #endif | |
125 | |
126 static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) | |
127 { | |
128 if(!size1 || !size2 || !size3) | |
129 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |
130 if(size1 > SIZE_MAX / size2) | |
131 return 0; | |
132 size1 *= size2; | |
133 if(size1 > SIZE_MAX / size3) | |
134 return 0; | |
135 return malloc(size1*size3); | |
136 } | |
137 | |
138 /* size1*size2 + size3 */ | |
139 static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) | |
140 { | |
141 if(!size1 || !size2) | |
142 return safe_malloc_(size3); | |
143 if(size1 > SIZE_MAX / size2) | |
144 return 0; | |
145 return safe_malloc_add_2op_(size1*size2, size3); | |
146 } | |
147 | |
148 /* size1 * (size2 + size3) */ | |
149 static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) | |
150 { | |
151 if(!size1 || (!size2 && !size3)) | |
152 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |
153 size2 += size3; | |
154 if(size2 < size3) | |
155 return 0; | |
156 return safe_malloc_mul_2op_(size1, size2); | |
157 } | |
158 | |
159 static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) | |
160 { | |
161 size2 += size1; | |
162 if(size2 < size1) | |
163 return 0; | |
164 return realloc(ptr, size2); | |
165 } | |
166 | |
167 static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) | |
168 { | |
169 size2 += size1; | |
170 if(size2 < size1) | |
171 return 0; | |
172 size3 += size2; | |
173 if(size3 < size2) | |
174 return 0; | |
175 return realloc(ptr, size3); | |
176 } | |
177 | |
178 static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) | |
179 { | |
180 size2 += size1; | |
181 if(size2 < size1) | |
182 return 0; | |
183 size3 += size2; | |
184 if(size3 < size2) | |
185 return 0; | |
186 size4 += size3; | |
187 if(size4 < size3) | |
188 return 0; | |
189 return realloc(ptr, size4); | |
190 } | |
191 | |
192 static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) | |
193 { | |
194 if(!size1 || !size2) | |
195 return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | |
196 if(size1 > SIZE_MAX / size2) | |
197 return 0; | |
198 return realloc(ptr, size1*size2); | |
199 } | |
200 | |
201 /* size1 * (size2 + size3) */ | |
202 static FLaC__INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) | |
203 { | |
204 if(!size1 || (!size2 && !size3)) | |
205 return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | |
206 size2 += size3; | |
207 if(size2 < size3) | |
208 return 0; | |
209 return safe_realloc_mul_2op_(ptr, size1, size2); | |
210 } | |
211 | |
212 #endif |