OLD | NEW |
1 /* libFLAC - Free Lossless Audio Codec library | 1 /* libFLAC - Free Lossless Audio Codec library |
2 * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | 2 * Copyright (C) 2001-2009 Josh Coalson |
| 3 * Copyright (C) 2011-2014 Xiph.Org Foundation |
3 * | 4 * |
4 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
6 * are met: | 7 * are met: |
7 * | 8 * |
8 * - Redistributions of source code must retain the above copyright | 9 * - Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
10 * | 11 * |
11 * - Redistributions in binary form must reproduce the above copyright | 12 * - Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 13 * notice, this list of conditions and the following disclaimer in the |
13 * documentation and/or other materials provided with the distribution. | 14 * documentation and/or other materials provided with the distribution. |
14 * | 15 * |
15 * - Neither the name of the Xiph.org Foundation nor the names of its | 16 * - Neither the name of the Xiph.org Foundation nor the names of its |
16 * contributors may be used to endorse or promote products derived from | 17 * contributors may be used to endorse or promote products derived from |
17 * this software without specific prior written permission. | 18 * this software without specific prior written permission. |
18 * | 19 * |
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 31 */ |
31 | 32 |
32 #if HAVE_CONFIG_H | 33 #ifdef HAVE_CONFIG_H |
33 # include <config.h> | 34 # include <config.h> |
34 #endif | 35 #endif |
35 | 36 |
| 37 #ifdef HAVE_STDINT_H |
| 38 #include <stdint.h> |
| 39 #endif |
| 40 |
36 #include "private/memory.h" | 41 #include "private/memory.h" |
37 #include "FLAC/assert.h" | 42 #include "FLAC/assert.h" |
38 #include "share/alloc.h" | 43 #include "share/alloc.h" |
39 | 44 |
40 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) | 45 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) |
41 { | 46 { |
42 void *x; | 47 void *x; |
43 | 48 |
44 FLAC__ASSERT(0 != aligned_address); | 49 FLAC__ASSERT(0 != aligned_address); |
45 | 50 |
46 #ifdef FLAC__ALIGN_MALLOC_DATA | 51 #ifdef FLAC__ALIGN_MALLOC_DATA |
47 /* align on 32-byte (256-bit) boundary */ | 52 /* align on 32-byte (256-bit) boundary */ |
48 » x = safe_malloc_add_2op_(bytes, /*+*/31); | 53 » x = safe_malloc_add_2op_(bytes, /*+*/31L); |
49 #ifdef SIZEOF_VOIDP | 54 » *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); |
50 #if SIZEOF_VOIDP == 4 | |
51 » » /* could do *aligned_address = x + ((unsigned) (32 - (((unsigne
d)x) & 31))) & 31; */ | |
52 » » *aligned_address = (void*)(((unsigned)x + 31) & -32); | |
53 #elif SIZEOF_VOIDP == 8 | |
54 » » *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint6
4)(-((FLAC__int64)32))); | |
55 #else | |
56 # error Unsupported sizeof(void*) | |
57 #endif | |
58 #else | |
59 » /* there's got to be a better way to do this right for all archs */ | |
60 » if(sizeof(void*) == sizeof(unsigned)) | |
61 » » *aligned_address = (void*)(((unsigned)x + 31) & -32); | |
62 » else if(sizeof(void*) == sizeof(FLAC__uint64)) | |
63 » » *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint6
4)(-((FLAC__int64)32))); | |
64 » else | |
65 » » return 0; | |
66 #endif | |
67 #else | 55 #else |
68 x = safe_malloc_(bytes); | 56 x = safe_malloc_(bytes); |
69 *aligned_address = x; | 57 *aligned_address = x; |
70 #endif | 58 #endif |
71 return x; | 59 return x; |
72 } | 60 } |
73 | 61 |
74 FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32
**unaligned_pointer, FLAC__int32 **aligned_pointer) | 62 FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 *
*unaligned_pointer, FLAC__int32 **aligned_pointer) |
75 { | 63 { |
76 FLAC__int32 *pu; /* unaligned pointer */ | 64 FLAC__int32 *pu; /* unaligned pointer */ |
77 union { /* union needed to comply with C99 pointer aliasing rules */ | 65 union { /* union needed to comply with C99 pointer aliasing rules */ |
78 FLAC__int32 *pa; /* aligned pointer */ | 66 FLAC__int32 *pa; /* aligned pointer */ |
79 void *pv; /* aligned pointer alias */ | 67 void *pv; /* aligned pointer alias */ |
80 } u; | 68 } u; |
81 | 69 |
82 FLAC__ASSERT(elements > 0); | 70 FLAC__ASSERT(elements > 0); |
83 FLAC__ASSERT(0 != unaligned_pointer); | 71 FLAC__ASSERT(0 != unaligned_pointer); |
84 FLAC__ASSERT(0 != aligned_pointer); | 72 FLAC__ASSERT(0 != aligned_pointer); |
85 FLAC__ASSERT(unaligned_pointer != aligned_pointer); | 73 FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
86 | 74 |
87 » if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | 75 » if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
88 return false; | 76 return false; |
89 | 77 |
90 » pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elem
ents, &u.pv); | 78 » pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
91 if(0 == pu) { | 79 if(0 == pu) { |
92 return false; | 80 return false; |
93 } | 81 } |
94 else { | 82 else { |
95 if(*unaligned_pointer != 0) | 83 if(*unaligned_pointer != 0) |
96 free(*unaligned_pointer); | 84 free(*unaligned_pointer); |
97 *unaligned_pointer = pu; | 85 *unaligned_pointer = pu; |
98 *aligned_pointer = u.pa; | 86 *aligned_pointer = u.pa; |
99 return true; | 87 return true; |
100 } | 88 } |
101 } | 89 } |
102 | 90 |
103 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint
32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) | 91 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32
**unaligned_pointer, FLAC__uint32 **aligned_pointer) |
104 { | 92 { |
105 FLAC__uint32 *pu; /* unaligned pointer */ | 93 FLAC__uint32 *pu; /* unaligned pointer */ |
106 union { /* union needed to comply with C99 pointer aliasing rules */ | 94 union { /* union needed to comply with C99 pointer aliasing rules */ |
107 FLAC__uint32 *pa; /* aligned pointer */ | 95 FLAC__uint32 *pa; /* aligned pointer */ |
108 void *pv; /* aligned pointer alias */ | 96 void *pv; /* aligned pointer alias */ |
109 } u; | 97 } u; |
110 | 98 |
111 FLAC__ASSERT(elements > 0); | 99 FLAC__ASSERT(elements > 0); |
112 FLAC__ASSERT(0 != unaligned_pointer); | 100 FLAC__ASSERT(0 != unaligned_pointer); |
113 FLAC__ASSERT(0 != aligned_pointer); | 101 FLAC__ASSERT(0 != aligned_pointer); |
114 FLAC__ASSERT(unaligned_pointer != aligned_pointer); | 102 FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
115 | 103 |
116 » if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | 104 » if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
117 return false; | 105 return false; |
118 | 106 |
119 » pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &
u.pv); | 107 » pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
120 if(0 == pu) { | 108 if(0 == pu) { |
121 return false; | 109 return false; |
122 } | 110 } |
123 else { | 111 else { |
124 if(*unaligned_pointer != 0) | 112 if(*unaligned_pointer != 0) |
125 free(*unaligned_pointer); | 113 free(*unaligned_pointer); |
126 *unaligned_pointer = pu; | 114 *unaligned_pointer = pu; |
127 *aligned_pointer = u.pa; | 115 *aligned_pointer = u.pa; |
128 return true; | 116 return true; |
129 } | 117 } |
130 } | 118 } |
131 | 119 |
132 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint
64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) | 120 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64
**unaligned_pointer, FLAC__uint64 **aligned_pointer) |
133 { | 121 { |
134 FLAC__uint64 *pu; /* unaligned pointer */ | 122 FLAC__uint64 *pu; /* unaligned pointer */ |
135 union { /* union needed to comply with C99 pointer aliasing rules */ | 123 union { /* union needed to comply with C99 pointer aliasing rules */ |
136 FLAC__uint64 *pa; /* aligned pointer */ | 124 FLAC__uint64 *pa; /* aligned pointer */ |
137 void *pv; /* aligned pointer alias */ | 125 void *pv; /* aligned pointer alias */ |
138 } u; | 126 } u; |
139 | 127 |
140 FLAC__ASSERT(elements > 0); | 128 FLAC__ASSERT(elements > 0); |
141 FLAC__ASSERT(0 != unaligned_pointer); | 129 FLAC__ASSERT(0 != unaligned_pointer); |
142 FLAC__ASSERT(0 != aligned_pointer); | 130 FLAC__ASSERT(0 != aligned_pointer); |
143 FLAC__ASSERT(unaligned_pointer != aligned_pointer); | 131 FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
144 | 132 |
145 » if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | 133 » if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
146 return false; | 134 return false; |
147 | 135 |
148 » pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &
u.pv); | 136 » pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
149 if(0 == pu) { | 137 if(0 == pu) { |
150 return false; | 138 return false; |
151 } | 139 } |
152 else { | 140 else { |
153 if(*unaligned_pointer != 0) | 141 if(*unaligned_pointer != 0) |
154 free(*unaligned_pointer); | 142 free(*unaligned_pointer); |
155 *unaligned_pointer = pu; | 143 *unaligned_pointer = pu; |
156 *aligned_pointer = u.pa; | 144 *aligned_pointer = u.pa; |
157 return true; | 145 return true; |
158 } | 146 } |
159 } | 147 } |
160 | 148 |
161 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned
**unaligned_pointer, unsigned **aligned_pointer) | 149 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned *
*unaligned_pointer, unsigned **aligned_pointer) |
162 { | 150 { |
163 unsigned *pu; /* unaligned pointer */ | 151 unsigned *pu; /* unaligned pointer */ |
164 union { /* union needed to comply with C99 pointer aliasing rules */ | 152 union { /* union needed to comply with C99 pointer aliasing rules */ |
165 unsigned *pa; /* aligned pointer */ | 153 unsigned *pa; /* aligned pointer */ |
166 void *pv; /* aligned pointer alias */ | 154 void *pv; /* aligned pointer alias */ |
167 } u; | 155 } u; |
168 | 156 |
169 FLAC__ASSERT(elements > 0); | 157 FLAC__ASSERT(elements > 0); |
170 FLAC__ASSERT(0 != unaligned_pointer); | 158 FLAC__ASSERT(0 != unaligned_pointer); |
171 FLAC__ASSERT(0 != aligned_pointer); | 159 FLAC__ASSERT(0 != aligned_pointer); |
172 FLAC__ASSERT(unaligned_pointer != aligned_pointer); | 160 FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
173 | 161 |
174 » if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | 162 » if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
175 return false; | 163 return false; |
176 | 164 |
177 » pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv
); | 165 » pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
178 if(0 == pu) { | 166 if(0 == pu) { |
179 return false; | 167 return false; |
180 } | 168 } |
181 else { | 169 else { |
182 if(*unaligned_pointer != 0) | 170 if(*unaligned_pointer != 0) |
183 free(*unaligned_pointer); | 171 free(*unaligned_pointer); |
184 *unaligned_pointer = pu; | 172 *unaligned_pointer = pu; |
185 *aligned_pointer = u.pa; | 173 *aligned_pointer = u.pa; |
186 return true; | 174 return true; |
187 } | 175 } |
188 } | 176 } |
189 | 177 |
190 #ifndef FLAC__INTEGER_ONLY_LIBRARY | 178 #ifndef FLAC__INTEGER_ONLY_LIBRARY |
191 | 179 |
192 FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real *
*unaligned_pointer, FLAC__real **aligned_pointer) | 180 FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **u
naligned_pointer, FLAC__real **aligned_pointer) |
193 { | 181 { |
194 FLAC__real *pu; /* unaligned pointer */ | 182 FLAC__real *pu; /* unaligned pointer */ |
195 union { /* union needed to comply with C99 pointer aliasing rules */ | 183 union { /* union needed to comply with C99 pointer aliasing rules */ |
196 FLAC__real *pa; /* aligned pointer */ | 184 FLAC__real *pa; /* aligned pointer */ |
197 void *pv; /* aligned pointer alias */ | 185 void *pv; /* aligned pointer alias */ |
198 } u; | 186 } u; |
199 | 187 |
200 FLAC__ASSERT(elements > 0); | 188 FLAC__ASSERT(elements > 0); |
201 FLAC__ASSERT(0 != unaligned_pointer); | 189 FLAC__ASSERT(0 != unaligned_pointer); |
202 FLAC__ASSERT(0 != aligned_pointer); | 190 FLAC__ASSERT(0 != aligned_pointer); |
203 FLAC__ASSERT(unaligned_pointer != aligned_pointer); | 191 FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
204 | 192 |
205 » if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | 193 » if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
206 return false; | 194 return false; |
207 | 195 |
208 » pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.
pv); | 196 » pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
209 if(0 == pu) { | 197 if(0 == pu) { |
210 return false; | 198 return false; |
211 } | 199 } |
212 else { | 200 else { |
213 if(*unaligned_pointer != 0) | 201 if(*unaligned_pointer != 0) |
214 free(*unaligned_pointer); | 202 free(*unaligned_pointer); |
215 *unaligned_pointer = pu; | 203 *unaligned_pointer = pu; |
216 *aligned_pointer = u.pa; | 204 *aligned_pointer = u.pa; |
217 return true; | 205 return true; |
218 } | 206 } |
219 } | 207 } |
220 | 208 |
221 #endif | 209 #endif |
| 210 |
| 211 void *safe_malloc_mul_2op_p(size_t size1, size_t size2) |
| 212 { |
| 213 if(!size1 || !size2) |
| 214 return malloc(1); /* malloc(0) is undefined; FLAC src convention
is to always allocate */ |
| 215 if(size1 > SIZE_MAX / size2) |
| 216 return 0; |
| 217 return malloc(size1*size2); |
| 218 } |
OLD | NEW |