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