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