Coverage Report

Created: 2026-04-12 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flac/src/libFLAC/format.c
Line
Count
Source
1
/* libFLAC - Free Lossless Audio Codec library
2
 * Copyright (C) 2000-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
#include <stdio.h>
38
#include <stdlib.h> /* for qsort() */
39
#include <string.h> /* for memset() */
40
#include "FLAC/assert.h"
41
#include "FLAC/format.h"
42
#include "share/alloc.h"
43
#include "share/compat.h"
44
#include "private/format.h"
45
#include "private/macros.h"
46
47
#if (defined GIT_COMMIT_HASH && defined GIT_COMMIT_DATE)
48
# ifdef GIT_COMMIT_TAG
49
FLAC_API const char *FLAC__VERSION_STRING = GIT_COMMIT_TAG;
50
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " GIT_COMMIT_TAG " " GIT_COMMIT_DATE;
51
# else
52
FLAC_API const char *FLAC__VERSION_STRING = "git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE;
53
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE;
54
# endif
55
#else
56
/* PACKAGE_VERSION should come from configure */
57
FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION;
58
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20250211";
59
#endif
60
61
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
62
FLAC_API const uint32_t FLAC__STREAM_SYNC = 0x664C6143;
63
FLAC_API const uint32_t FLAC__STREAM_SYNC_LEN = 32; /* bits */
64
65
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
66
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
67
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
68
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
69
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
70
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
71
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
72
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
73
FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
74
75
FLAC_API const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
76
77
FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
78
FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
79
FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
80
81
FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
82
83
FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
84
FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
85
86
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
87
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
88
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
89
90
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
91
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
92
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
93
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
94
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
95
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
96
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
97
98
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
99
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
100
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
101
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
102
FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
103
104
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
105
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
106
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
107
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
108
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
109
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
110
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
111
FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
112
113
FLAC_API const uint32_t FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
114
FLAC_API const uint32_t FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
115
FLAC_API const uint32_t FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
116
117
FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC = 0x3ffe;
118
FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
119
FLAC_API const uint32_t FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
120
FLAC_API const uint32_t FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
121
FLAC_API const uint32_t FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
122
FLAC_API const uint32_t FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
123
FLAC_API const uint32_t FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
124
FLAC_API const uint32_t FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
125
FLAC_API const uint32_t FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
126
FLAC_API const uint32_t FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
127
128
FLAC_API const uint32_t FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
129
130
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
131
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
132
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
133
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
134
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
135
136
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
137
FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
138
139
FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
140
  "PARTITIONED_RICE",
141
  "PARTITIONED_RICE2"
142
};
143
144
FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
145
FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
146
147
FLAC_API const uint32_t FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
148
FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
149
FLAC_API const uint32_t FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
150
151
FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
152
FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
153
FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
154
FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
155
156
FLAC_API const char * const FLAC__SubframeTypeString[] = {
157
  "CONSTANT",
158
  "VERBATIM",
159
  "FIXED",
160
  "LPC"
161
};
162
163
FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
164
  "INDEPENDENT",
165
  "LEFT_SIDE",
166
  "RIGHT_SIDE",
167
  "MID_SIDE"
168
};
169
170
FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
171
  "FRAME_NUMBER_TYPE_FRAME_NUMBER",
172
  "FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
173
};
174
175
FLAC_API const char * const FLAC__MetadataTypeString[] = {
176
  "STREAMINFO",
177
  "PADDING",
178
  "APPLICATION",
179
  "SEEKTABLE",
180
  "VORBIS_COMMENT",
181
  "CUESHEET",
182
  "PICTURE"
183
};
184
185
FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
186
  "Other",
187
  "32x32 pixels 'file icon' (PNG only)",
188
  "Other file icon",
189
  "Cover (front)",
190
  "Cover (back)",
191
  "Leaflet page",
192
  "Media (e.g. label side of CD)",
193
  "Lead artist/lead performer/soloist",
194
  "Artist/performer",
195
  "Conductor",
196
  "Band/Orchestra",
197
  "Composer",
198
  "Lyricist/text writer",
199
  "Recording Location",
200
  "During recording",
201
  "During performance",
202
  "Movie/video screen capture",
203
  "A bright coloured fish",
204
  "Illustration",
205
  "Band/artist logotype",
206
  "Publisher/Studio logotype"
207
};
208
209
FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(uint32_t sample_rate)
210
7.72M
{
211
7.72M
  if(sample_rate > FLAC__MAX_SAMPLE_RATE) {
212
240
    return false;
213
240
  }
214
7.72M
  else
215
7.72M
    return true;
216
7.72M
}
217
218
FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_t sample_rate)
219
23.9k
{
220
23.9k
  if(blocksize > 16384)
221
118
    return false;
222
23.8k
  else if(sample_rate <= 48000 && blocksize > 4608)
223
112
    return false;
224
23.7k
  else
225
23.7k
    return true;
226
23.9k
}
227
228
FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate)
229
23.7k
{
230
23.7k
  if( // sample rate is not subset if
231
23.7k
    !FLAC__format_sample_rate_is_valid(sample_rate) || // sample rate is invalid or
232
23.7k
    sample_rate >= ((1u << 16) * 10) || // sample rate is larger then or equal to 655360 or
233
23.5k
    (sample_rate >= (1u << 16) && sample_rate % 10 != 0) //sample rate is >= 65536 and not divisible by 10
234
23.7k
  ) {
235
947
    return false;
236
947
  }
237
22.8k
  else
238
22.8k
    return true;
239
23.7k
}
240
241
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
242
FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
243
28.0k
{
244
28.0k
  uint32_t i;
245
28.0k
  FLAC__uint64 prev_sample_number = 0;
246
28.0k
  FLAC__bool got_prev = false;
247
248
28.0k
  FLAC__ASSERT(0 != seek_table);
249
250
28.0k
  if((FLAC__uint64)(seek_table->num_points) * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN))
251
0
    return false;
252
253
267M
  for(i = 0; i < seek_table->num_points; i++) {
254
267M
    if(got_prev) {
255
267M
      if(
256
267M
        seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
257
193M
        seek_table->points[i].sample_number <= prev_sample_number
258
267M
      )
259
544
        return false;
260
267M
    }
261
267M
    prev_sample_number = seek_table->points[i].sample_number;
262
267M
    got_prev = true;
263
267M
  }
264
265
27.5k
  return true;
266
28.0k
}
267
268
/* used as the sort predicate for qsort() */
269
static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
270
3.15G
{
271
  /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
272
3.15G
  if(l->sample_number == r->sample_number)
273
757M
    return 0;
274
2.39G
  else if(l->sample_number < r->sample_number)
275
2.30G
    return -1;
276
90.5M
  else
277
90.5M
    return 1;
278
3.15G
}
279
280
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
281
FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
282
28.7k
{
283
28.7k
  uint32_t i, j;
284
28.7k
  FLAC__bool first;
285
286
28.7k
  FLAC__ASSERT(0 != seek_table);
287
288
28.7k
  if (seek_table->num_points == 0)
289
12.0k
    return 0;
290
291
  /* sort the seekpoints */
292
16.6k
  qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
293
294
  /* uniquify the seekpoints */
295
16.6k
  first = true;
296
364M
  for(i = j = 0; i < seek_table->num_points; i++) {
297
364M
    if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
298
291M
      if(!first) {
299
291M
        if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
300
75.0M
          continue;
301
291M
      }
302
291M
    }
303
289M
    first = false;
304
289M
    seek_table->points[j++] = seek_table->points[i];
305
289M
  }
306
307
75.0M
  for(i = j; i < seek_table->num_points; i++) {
308
75.0M
    seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
309
75.0M
    seek_table->points[i].stream_offset = 0;
310
75.0M
    seek_table->points[i].frame_samples = 0;
311
75.0M
  }
312
313
16.6k
  return j;
314
28.7k
}
315
316
/*
317
 * also disallows non-shortest-form encodings, c.f.
318
 *   http://www.unicode.org/versions/corrigendum1.html
319
 * and a more clear explanation at the end of this section:
320
 *   http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
321
 */
322
static uint32_t utf8len_(const FLAC__byte *utf8)
323
22.3M
{
324
22.3M
  FLAC__ASSERT(0 != utf8);
325
22.3M
  if ((utf8[0] & 0x80) == 0) {
326
22.2M
    return 1;
327
22.2M
  }
328
75.5k
  else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
329
10.8k
    if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
330
144
      return 0;
331
10.6k
    return 2;
332
10.8k
  }
333
64.7k
  else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
334
7.73k
    if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
335
272
      return 0;
336
    /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
337
7.46k
    if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
338
274
      return 0;
339
7.18k
    if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
340
95
      return 0;
341
7.09k
    return 3;
342
7.18k
  }
343
57.0k
  else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
344
37.2k
    if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
345
147
      return 0;
346
37.1k
    return 4;
347
37.2k
  }
348
19.7k
  else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
349
8.67k
    if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
350
111
      return 0;
351
8.56k
    return 5;
352
8.67k
  }
353
11.0k
  else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) {
354
5.16k
    if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
355
273
      return 0;
356
4.88k
    return 6;
357
5.16k
  }
358
5.90k
  else {
359
5.90k
    return 0;
360
5.90k
  }
361
22.3M
}
362
363
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
364
8.27k
{
365
8.27k
  char c;
366
844k
  for(c = *name; c; c = *(++name))
367
836k
    if(c < 0x20 || c == 0x3d || c > 0x7d)
368
0
      return false;
369
8.27k
  return true;
370
8.27k
}
371
372
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length)
373
8.27k
{
374
8.27k
  if(length == (uint32_t)(-1)) {
375
212k
    while(*value) {
376
204k
      uint32_t n = utf8len_(value);
377
204k
      if(n == 0)
378
0
        return false;
379
204k
      value += n;
380
204k
    }
381
8.27k
  }
382
0
  else {
383
0
    const FLAC__byte *end = value + length;
384
0
    while(value < end) {
385
0
      uint32_t n = utf8len_(value);
386
0
      if(n == 0)
387
0
        return false;
388
0
      value += n;
389
0
    }
390
0
    if(value != end)
391
0
      return false;
392
0
  }
393
8.27k
  return true;
394
8.27k
}
395
396
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length)
397
129k
{
398
129k
  const FLAC__byte *s, *end;
399
400
11.3M
  for(s = entry, end = s + length; s < end && *s != '='; s++) {
401
11.2M
    if(*s < 0x20 || *s > 0x7D)
402
23
      return false;
403
11.2M
  }
404
129k
  if(s == end)
405
136
    return false;
406
407
129k
  s++; /* skip '=' */
408
409
22.0M
  while(s < end) {
410
21.9M
    uint32_t n = utf8len_(s);
411
21.9M
    if(n == 0)
412
1.32k
      return false;
413
21.9M
    s += n;
414
21.9M
  }
415
128k
  if(s != end)
416
0
    return false;
417
418
128k
  return true;
419
128k
}
420
421
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
422
FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
423
12.1k
{
424
12.1k
  uint32_t i, j;
425
426
12.1k
  if(check_cd_da_subset) {
427
6.02k
    if(cue_sheet->lead_in < 2 * 44100) {
428
134
      if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
429
134
      return false;
430
134
    }
431
5.89k
    if(cue_sheet->lead_in % 588 != 0) {
432
771
      if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
433
771
      return false;
434
771
    }
435
5.89k
  }
436
437
11.2k
  if(cue_sheet->num_tracks == 0) {
438
16
    if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
439
16
    return false;
440
16
  }
441
442
11.2k
  if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
443
208
    if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
444
208
    return false;
445
208
  }
446
447
90.2k
  for(i = 0; i < cue_sheet->num_tracks; i++) {
448
84.2k
    if(cue_sheet->tracks[i].number == 0) {
449
144
      if(violation) *violation = "cue sheet may not have a track number 0";
450
144
      return false;
451
144
    }
452
453
84.0k
    if(check_cd_da_subset) {
454
8.79k
      if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
455
1.19k
        if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
456
1.19k
        return false;
457
1.19k
      }
458
8.79k
    }
459
460
82.8k
    if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
461
448
      if(violation) {
462
98
        if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
463
98
          *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
464
0
        else
465
0
          *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
466
98
      }
467
448
      return false;
468
448
    }
469
470
82.4k
    if(i < cue_sheet->num_tracks - 1) {
471
76.3k
      if(cue_sheet->tracks[i].num_indices == 0) {
472
71
        if(violation) *violation = "cue sheet track must have at least one index point";
473
71
        return false;
474
71
      }
475
476
76.2k
      if(cue_sheet->tracks[i].indices[0].number > 1) {
477
303
        if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
478
303
        return false;
479
303
      }
480
76.2k
    }
481
482
189k
    for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
483
110k
      if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
484
2.20k
        if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
485
2.20k
        return false;
486
2.20k
      }
487
488
107k
      if(j > 0) {
489
27.6k
        if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
490
674
          if(violation) *violation = "cue sheet track index numbers must increase by 1";
491
674
          return false;
492
674
        }
493
27.6k
      }
494
107k
    }
495
82.0k
  }
496
497
6.00k
  return true;
498
11.0k
}
499
500
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
501
FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
502
17.5k
{
503
17.5k
  char *p;
504
17.5k
  FLAC__byte *b;
505
506
31.0k
  for(p = picture->mime_type; *p; p++) {
507
15.1k
    if(*p < 0x20 || *p > 0x7e) {
508
1.69k
      if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
509
1.69k
      return false;
510
1.69k
    }
511
15.1k
  }
512
513
213k
  for(b = picture->description; *b; ) {
514
203k
    uint32_t n = utf8len_(b);
515
203k
    if(n == 0) {
516
5.89k
      if(violation) *violation = "description string must be valid UTF-8";
517
5.89k
      return false;
518
5.89k
    }
519
197k
    b += n;
520
197k
  }
521
522
9.96k
  return true;
523
15.8k
}
524
525
/*
526
 * These routines are private to libFLAC
527
 */
528
#if 0 /* UNUSED */
529
uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order)
530
{
531
  return
532
    FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
533
      FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
534
      blocksize,
535
      predictor_order
536
    );
537
}
538
#endif
539
540
uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize)
541
7.59M
{
542
7.59M
  uint32_t max_rice_partition_order = 0;
543
29.1M
  while(!(blocksize & 1)) {
544
21.5M
    max_rice_partition_order++;
545
21.5M
    blocksize >>= 1;
546
21.5M
  }
547
7.59M
  return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
548
7.59M
}
549
550
uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit, uint32_t blocksize, uint32_t predictor_order)
551
39.9M
{
552
39.9M
  uint32_t max_rice_partition_order = limit;
553
554
59.5M
  while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
555
19.5M
    max_rice_partition_order--;
556
557
39.9M
  FLAC__ASSERT(
558
39.9M
    (max_rice_partition_order == 0 && blocksize >= predictor_order) ||
559
39.9M
    (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
560
39.9M
  );
561
562
39.9M
  return max_rice_partition_order;
563
39.9M
}
564
565
void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
566
12.3M
{
567
12.3M
  FLAC__ASSERT(0 != object);
568
569
12.3M
  object->parameters = 0;
570
12.3M
  object->raw_bits = 0;
571
12.3M
  object->capacity_by_order = 0;
572
12.3M
}
573
574
void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
575
6.68M
{
576
6.68M
  FLAC__ASSERT(0 != object);
577
578
6.68M
  if(0 != object->parameters)
579
1.95M
    free(object->parameters);
580
6.68M
  if(0 != object->raw_bits)
581
1.95M
    free(object->raw_bits);
582
6.68M
  FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
583
6.68M
}
584
585
#if defined(_MSC_VER)
586
// silence three MSVC warnings 'result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)'
587
#pragma warning ( disable : 4334 )
588
#endif
589
590
FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order)
591
5.23M
{
592
5.23M
  FLAC__ASSERT(0 != object);
593
594
5.23M
  if(object->capacity_by_order < max_partition_order || object->parameters == NULL || object->raw_bits == NULL) {
595
1.95M
    if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order))))
596
136
      return false;
597
1.95M
    if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order))))
598
114
      return false;
599
1.95M
    memset(object->raw_bits, 0, sizeof(uint32_t)*(1 << max_partition_order));
600
1.95M
    object->capacity_by_order = max_partition_order;
601
1.95M
  }
602
603
5.23M
  return true;
604
5.23M
}
605
606
#if defined(_MSC_VER)
607
#pragma warning ( default : 4334 )
608
#endif