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