| 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 |