1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2001-2009 Josh Coalson
3 * Copyright (C) 2011-2016 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 #include <stdint.h>
34 #include "private/memory.h"
35 #include "share/compat.h"
36 #include "share/alloc.h"
37
FLAC__memory_alloc_aligned(size_t bytes,void ** aligned_address)38 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
39 {
40 void *x;
41
42 x = safe_malloc_(bytes);
43 *aligned_address = x;
44
45 return x;
46 }
47
FLAC__memory_alloc_aligned_int32_array(size_t elements,FLAC__int32 ** unaligned_pointer,FLAC__int32 ** aligned_pointer)48 FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
49 {
50 FLAC__int32 *pu; /* unaligned pointer */
51 union { /* union needed to comply with C99 pointer aliasing rules */
52 FLAC__int32 *pa; /* aligned pointer */
53 void *pv; /* aligned pointer alias */
54 } u;
55
56 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
57 return false;
58
59 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
60 if(0 == pu) {
61 return false;
62 }
63 else {
64 if(*unaligned_pointer != 0)
65 free(*unaligned_pointer);
66 *unaligned_pointer = pu;
67 *aligned_pointer = u.pa;
68 return true;
69 }
70 }
71
FLAC__memory_alloc_aligned_uint32_array(size_t elements,FLAC__uint32 ** unaligned_pointer,FLAC__uint32 ** aligned_pointer)72 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
73 {
74 FLAC__uint32 *pu; /* unaligned pointer */
75 union { /* union needed to comply with C99 pointer aliasing rules */
76 FLAC__uint32 *pa; /* aligned pointer */
77 void *pv; /* aligned pointer alias */
78 } u;
79
80 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
81 return false;
82
83 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
84 if(0 == pu) {
85 return false;
86 }
87 else {
88 if(*unaligned_pointer != 0)
89 free(*unaligned_pointer);
90 *unaligned_pointer = pu;
91 *aligned_pointer = u.pa;
92 return true;
93 }
94 }
95
FLAC__memory_alloc_aligned_uint64_array(size_t elements,FLAC__uint64 ** unaligned_pointer,FLAC__uint64 ** aligned_pointer)96 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
97 {
98 FLAC__uint64 *pu; /* unaligned pointer */
99 union { /* union needed to comply with C99 pointer aliasing rules */
100 FLAC__uint64 *pa; /* aligned pointer */
101 void *pv; /* aligned pointer alias */
102 } u;
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
FLAC__memory_alloc_aligned_unsigned_array(size_t elements,uint32_t ** unaligned_pointer,uint32_t ** aligned_pointer)120 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer)
121 {
122 uint32_t *pu; /* unaligned pointer */
123 union { /* union needed to comply with C99 pointer aliasing rules */
124 uint32_t *pa; /* aligned pointer */
125 void *pv; /* aligned pointer alias */
126 } u;
127
128 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
129 return false;
130
131 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
132 if(0 == pu) {
133 return false;
134 }
135 else {
136 if(*unaligned_pointer != 0)
137 free(*unaligned_pointer);
138 *unaligned_pointer = pu;
139 *aligned_pointer = u.pa;
140 return true;
141 }
142 }
143
FLAC__memory_alloc_aligned_real_array(size_t elements,FLAC__real ** unaligned_pointer,FLAC__real ** aligned_pointer)144 FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
145 {
146 FLAC__real *pu; /* unaligned pointer */
147 union { /* union needed to comply with C99 pointer aliasing rules */
148 FLAC__real *pa; /* aligned pointer */
149 void *pv; /* aligned pointer alias */
150 } u;
151
152 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
153 return false;
154
155 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
156 if(0 == pu) {
157 return false;
158 }
159 else {
160 if(*unaligned_pointer != 0)
161 free(*unaligned_pointer);
162 *unaligned_pointer = pu;
163 *aligned_pointer = u.pa;
164 return true;
165 }
166 }
167
safe_malloc_mul_2op_p(size_t size1,size_t size2)168 void *safe_malloc_mul_2op_p(size_t size1, size_t size2)
169 {
170 if(!size1 || !size2)
171 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
172 if(size1 > SIZE_MAX / size2)
173 return 0;
174 return malloc(size1*size2);
175 }
176