Coverage Report

Created: 2025-07-11 06:51

/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
}