/src/flac/src/libFLAC/memory.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* libFLAC - Free Lossless Audio Codec library |
2 | | * Copyright (C) 2001-2009 Josh Coalson |
3 | | * Copyright (C) 2011-2025 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/compat.h" |
44 | | #include "share/alloc.h" |
45 | | |
46 | | void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) |
47 | 51.3k | { |
48 | 51.3k | void *x; |
49 | | |
50 | 51.3k | FLAC__ASSERT(0 != aligned_address); |
51 | | |
52 | 51.3k | #ifdef FLAC__ALIGN_MALLOC_DATA |
53 | | /* align on 32-byte (256-bit) boundary */ |
54 | 51.3k | x = safe_malloc_add_2op_(bytes, /*+*/31L); |
55 | 51.3k | *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); |
56 | | #else |
57 | | x = safe_malloc_(bytes); |
58 | | *aligned_address = x; |
59 | | #endif |
60 | 51.3k | return x; |
61 | 51.3k | } |
62 | | |
63 | | FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) |
64 | 51.3k | { |
65 | 51.3k | FLAC__int32 *pu; /* unaligned pointer */ |
66 | 51.3k | union { /* union needed to comply with C99 pointer aliasing rules */ |
67 | 51.3k | FLAC__int32 *pa; /* aligned pointer */ |
68 | 51.3k | void *pv; /* aligned pointer alias */ |
69 | 51.3k | } u; |
70 | | |
71 | 51.3k | FLAC__ASSERT(elements > 0); |
72 | 51.3k | FLAC__ASSERT(0 != unaligned_pointer); |
73 | 51.3k | FLAC__ASSERT(0 != aligned_pointer); |
74 | 51.3k | FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
75 | | |
76 | 51.3k | if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
77 | 0 | return false; |
78 | | |
79 | 51.3k | pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
80 | 51.3k | if(0 == pu) { |
81 | 0 | return false; |
82 | 0 | } |
83 | 51.3k | else { |
84 | 51.3k | if(*unaligned_pointer != 0) |
85 | 0 | free(*unaligned_pointer); |
86 | 51.3k | *unaligned_pointer = pu; |
87 | 51.3k | *aligned_pointer = u.pa; |
88 | 51.3k | return true; |
89 | 51.3k | } |
90 | 51.3k | } |
91 | | |
92 | | FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) |
93 | 0 | { |
94 | 0 | FLAC__uint32 *pu; /* unaligned pointer */ |
95 | 0 | union { /* union needed to comply with C99 pointer aliasing rules */ |
96 | 0 | FLAC__uint32 *pa; /* aligned pointer */ |
97 | 0 | void *pv; /* aligned pointer alias */ |
98 | 0 | } u; |
99 | |
|
100 | 0 | FLAC__ASSERT(elements > 0); |
101 | 0 | FLAC__ASSERT(0 != unaligned_pointer); |
102 | 0 | FLAC__ASSERT(0 != aligned_pointer); |
103 | 0 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
104 | |
|
105 | 0 | if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
106 | 0 | return false; |
107 | | |
108 | 0 | pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
109 | 0 | if(0 == pu) { |
110 | 0 | return false; |
111 | 0 | } |
112 | 0 | else { |
113 | 0 | if(*unaligned_pointer != 0) |
114 | 0 | free(*unaligned_pointer); |
115 | 0 | *unaligned_pointer = pu; |
116 | 0 | *aligned_pointer = u.pa; |
117 | 0 | return true; |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer) |
122 | 0 | { |
123 | 0 | FLAC__int64 *pu; /* unaligned pointer */ |
124 | 0 | union { /* union needed to comply with C99 pointer aliasing rules */ |
125 | 0 | FLAC__int64 *pa; /* aligned pointer */ |
126 | 0 | void *pv; /* aligned pointer alias */ |
127 | 0 | } u; |
128 | |
|
129 | 0 | FLAC__ASSERT(elements > 0); |
130 | 0 | FLAC__ASSERT(0 != unaligned_pointer); |
131 | 0 | FLAC__ASSERT(0 != aligned_pointer); |
132 | 0 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
133 | |
|
134 | 0 | if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
135 | 0 | return false; |
136 | | |
137 | 0 | pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
138 | 0 | if(0 == pu) { |
139 | 0 | return false; |
140 | 0 | } |
141 | 0 | else { |
142 | 0 | if(*unaligned_pointer != 0) |
143 | 0 | free(*unaligned_pointer); |
144 | 0 | *unaligned_pointer = pu; |
145 | 0 | *aligned_pointer = u.pa; |
146 | 0 | return true; |
147 | 0 | } |
148 | 0 | } |
149 | | |
150 | | FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) |
151 | 0 | { |
152 | 0 | FLAC__uint64 *pu; /* unaligned pointer */ |
153 | 0 | union { /* union needed to comply with C99 pointer aliasing rules */ |
154 | 0 | FLAC__uint64 *pa; /* aligned pointer */ |
155 | 0 | void *pv; /* aligned pointer alias */ |
156 | 0 | } u; |
157 | |
|
158 | 0 | FLAC__ASSERT(elements > 0); |
159 | 0 | FLAC__ASSERT(0 != unaligned_pointer); |
160 | 0 | FLAC__ASSERT(0 != aligned_pointer); |
161 | 0 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
162 | |
|
163 | 0 | if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
164 | 0 | return false; |
165 | | |
166 | 0 | pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
167 | 0 | if(0 == pu) { |
168 | 0 | return false; |
169 | 0 | } |
170 | 0 | else { |
171 | 0 | if(*unaligned_pointer != 0) |
172 | 0 | free(*unaligned_pointer); |
173 | 0 | *unaligned_pointer = pu; |
174 | 0 | *aligned_pointer = u.pa; |
175 | 0 | return true; |
176 | 0 | } |
177 | 0 | } |
178 | | |
179 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
180 | | |
181 | | FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) |
182 | 0 | { |
183 | 0 | FLAC__real *pu; /* unaligned pointer */ |
184 | 0 | union { /* union needed to comply with C99 pointer aliasing rules */ |
185 | 0 | FLAC__real *pa; /* aligned pointer */ |
186 | 0 | void *pv; /* aligned pointer alias */ |
187 | 0 | } u; |
188 | |
|
189 | 0 | FLAC__ASSERT(elements > 0); |
190 | 0 | FLAC__ASSERT(0 != unaligned_pointer); |
191 | 0 | FLAC__ASSERT(0 != aligned_pointer); |
192 | 0 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); |
193 | |
|
194 | 0 | if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ |
195 | 0 | return false; |
196 | | |
197 | 0 | pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); |
198 | 0 | if(0 == pu) { |
199 | 0 | return false; |
200 | 0 | } |
201 | 0 | else { |
202 | 0 | if(*unaligned_pointer != 0) |
203 | 0 | free(*unaligned_pointer); |
204 | 0 | *unaligned_pointer = pu; |
205 | 0 | *aligned_pointer = u.pa; |
206 | 0 | return true; |
207 | 0 | } |
208 | 0 | } |
209 | | |
210 | | #endif |
211 | | |
212 | | void *safe_malloc_mul_2op_p(size_t size1, size_t size2) |
213 | 6.24k | { |
214 | 6.24k | if(!size1 || !size2) |
215 | 0 | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ |
216 | 6.24k | if(size1 > SIZE_MAX / size2) |
217 | 0 | return 0; |
218 | 6.24k | return malloc(size1*size2); |
219 | 6.24k | } |