Coverage Report

Created: 2025-07-11 06:54

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