aboutsummaryrefslogtreecommitdiff
path: root/src/flac
diff options
context:
space:
mode:
Diffstat (limited to 'src/flac')
-rw-r--r--src/flac/CMakeLists.txt1
-rw-r--r--src/flac/Makefile.am22
-rw-r--r--src/flac/analyze.c5
-rw-r--r--src/flac/analyze.h2
-rw-r--r--src/flac/decode.c43
-rw-r--r--src/flac/decode.h2
-rw-r--r--src/flac/encode.c208
-rw-r--r--src/flac/encode.h6
-rw-r--r--src/flac/foreign_metadata.c9
-rw-r--r--src/flac/foreign_metadata.h2
-rw-r--r--src/flac/iffscan.c2
-rw-r--r--src/flac/local_string_utils.h2
-rw-r--r--src/flac/main.c76
-rw-r--r--src/flac/utils.c26
-rw-r--r--src/flac/utils.h4
-rw-r--r--src/flac/version.rc38
-rw-r--r--src/flac/vorbiscomment.c2
-rw-r--r--src/flac/vorbiscomment.h2
18 files changed, 208 insertions, 244 deletions
diff --git a/src/flac/CMakeLists.txt b/src/flac/CMakeLists.txt
index 40034502..da7ce8de 100644
--- a/src/flac/CMakeLists.txt
+++ b/src/flac/CMakeLists.txt
@@ -10,6 +10,7 @@ add_executable(flacapp
local_string_utils.c
utils.c
vorbiscomment.c
+ version.rc
$<$<BOOL:${WIN32}>:../../include/share/win_utf8_io.h>
$<$<BOOL:${WIN32}>:../share/win_utf8_io/win_utf8_io.c>)
set_property(TARGET flacapp PROPERTY RUNTIME_OUTPUT_NAME flac)
diff --git a/src/flac/Makefile.am b/src/flac/Makefile.am
index 5fc34386..279a7cb9 100644
--- a/src/flac/Makefile.am
+++ b/src/flac/Makefile.am
@@ -1,6 +1,6 @@
# flac - Command-line FLAC encoder/decoder
# Copyright (C) 2000-2009 Josh Coalson
-# Copyright (C) 2011-2022 Xiph.Org Foundation
+# Copyright (C) 2011-2023 Xiph.Org Foundation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -16,13 +16,22 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+if OS_IS_WINDOWS
+win_utf8_lib = $(top_builddir)/src/share/win_utf8_io/libwin_utf8_io.la
+if HAVE_WINDRES
+flac_DEPENDENCIES = version.o
+windows_resource_link = -Wl,version.o
+endif
+endif
+
bin_PROGRAMS = flac
AM_CFLAGS = @OGG_CFLAGS@
AM_CPPFLAGS = -I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include
EXTRA_DIST = \
CMakeLists.txt \
- iffscan.c
+ iffscan.c \
+ version.rc
flac_SOURCES = \
analyze.c \
@@ -41,10 +50,6 @@ flac_SOURCES = \
utils.h \
vorbiscomment.h
-if OS_IS_WINDOWS
-win_utf8_lib = $(top_builddir)/src/share/win_utf8_io/libwin_utf8_io.la
-endif
-
flac_LDADD = \
$(top_builddir)/src/share/utf8/libutf8.la \
$(top_builddir)/src/share/grabbag/libgrabbag.la \
@@ -56,4 +61,9 @@ flac_LDADD = \
@LTLIBICONV@ \
-lm
+flac_LDFLAGS = $(AM_LDFLAGS) $(windows_resource_link)
+
CLEANFILES = flac.exe
+
+.rc.o:
+ $(RC) $(AM_CPPFLAGS) $< $@
diff --git a/src/flac/analyze.c b/src/flac/analyze.c
index ff1b170d..0a85565e 100644
--- a/src/flac/analyze.c
+++ b/src/flac/analyze.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -245,5 +245,8 @@ FLAC__bool dump_stats(const subframe_stats_t *stats, const char *filename)
fprintf(outfile, "pause -1 'waiting...'\n");
fclose(outfile);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ unlink(filename);
+#endif
return true;
}
diff --git a/src/flac/analyze.h b/src/flac/analyze.h
index fbdec29e..ce07b145 100644
--- a/src/flac/analyze.h
+++ b/src/flac/analyze.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/flac/decode.c b/src/flac/decode.c
index c9c74546..90f7a6c8 100644
--- a/src/flac/decode.c
+++ b/src/flac/decode.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -242,7 +242,7 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d->has_md5sum = false;
d->bps = 0;
d->channels = 0;
- d->sample_rate = 0;
+ d->sample_rate = UINT32_MAX;
d->channel_mask = 0;
d->decode_position = 0;
@@ -297,7 +297,11 @@ void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
}
#endif
fclose(d->fout);
+
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /* Always delete output file when fuzzing */
if(error_occurred)
+#endif
flac_unlink(d->outfilename);
}
}
@@ -586,7 +590,10 @@ int DecoderSession_finish_error(DecoderSession *d)
FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, uint32_t sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
{
/* convert from mm:ss.sss to sample number if necessary */
- flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
+ if(!flac__utils_canonicalize_skip_until_specification(spec, sample_rate)) {
+ flac__utils_printf(stderr, 1, "%s: ERROR, value of --until is too large\n", inbasefilename);
+ return false;
+ }
/* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
if(spec->is_relative && spec->value.samples == 0) {
@@ -707,7 +714,7 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
else if(format == FORMAT_AIFF)
iff_size = 46 + foreign_metadata_size + aligned_data_size;
else /* AIFF-C */
- iff_size = 16 + foreign_metadata_size + aligned_data_size + fm->aifc_comm_length;
+ iff_size = 16 + foreign_metadata_size + aligned_data_size + (fm?fm->aifc_comm_length:0);
if(format != FORMAT_WAVE64 && format != FORMAT_RF64 && iff_size >= 0xFFFFFFF4) {
flac__utils_printf(stderr, 1, "%s: ERROR: stream is too big to fit in a single %s file\n", decoder_session->inbasefilename, fmt_desc);
@@ -1095,7 +1102,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
DecoderSession *decoder_session = (DecoderSession*)client_data;
FILE *fout = decoder_session->fout;
const uint32_t bps = frame->header.bits_per_sample, channels = frame->header.channels;
- const uint32_t shift = (decoder_session->format != FORMAT_RAW && (bps%8))? 8-(bps%8): 0;
+ const uint32_t shift = (bps%8)? 8-(bps%8): 0;
FLAC__bool is_big_endian = (
(decoder_session->format == FORMAT_AIFF || (decoder_session->format == FORMAT_AIFF_C && decoder_session->subformat == SUBFORMAT_AIFF_C_NONE)) ? true : (
decoder_session->format == FORMAT_WAVE || decoder_session->format == FORMAT_WAVE64 || decoder_session->format == FORMAT_RF64 || (decoder_session->format == FORMAT_AIFF_C && decoder_session->subformat == SUBFORMAT_AIFF_C_SOWT) ? false :
@@ -1140,6 +1147,10 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
else {
/* must not have gotten STREAMINFO, save the bps from the frame header */
FLAC__ASSERT(!decoder_session->got_stream_info);
+ if(decoder_session->format == FORMAT_RAW && ((decoder_session->bps % 8) != 0 || decoder_session->bps < 4)) {
+ flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is %u, must be 8/16/24/32 for raw format output\n", decoder_session->inbasefilename, decoder_session->bps);
+ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ }
decoder_session->bps = bps;
}
@@ -1161,7 +1172,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
}
/* sanity-check the sample rate */
- if(!decoder_session->got_stream_info) {
+ if(decoder_session->sample_rate < UINT32_MAX) {
if(frame->header.sample_rate != decoder_session->sample_rate) {
if(decoder_session->got_stream_info)
flac__utils_printf(stderr, 1, "%s: ERROR, sample rate is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate);
@@ -1172,15 +1183,16 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
}
}
else {
+ /* must not have gotten STREAMINFO, save the sample rate from the frame header */
+ FLAC__ASSERT(!decoder_session->got_stream_info);
decoder_session->sample_rate = frame->header.sample_rate;
}
/*
* limit the number of samples to accept based on --until
*/
- FLAC__ASSERT(!decoder_session->skip_specification->is_relative);
/* if we never got the total_samples from the metadata, the skip and until specs would never have been canonicalized, so protect against that: */
- if(decoder_session->skip_specification->is_relative) {
+ if(decoder_session->skip_specification->is_relative || !decoder_session->got_stream_info) {
if(decoder_session->skip_specification->value.samples == 0) /* special case for when no --skip was given */
decoder_session->skip_specification->is_relative = false; /* convert to our meaning of beginning-of-stream */
else {
@@ -1188,7 +1200,7 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
}
- if(decoder_session->until_specification->is_relative) {
+ if(decoder_session->until_specification->is_relative || !decoder_session->got_stream_info) {
if(decoder_session->until_specification->value.samples == 0) /* special case for when no --until was given */
decoder_session->until_specification->is_relative = false; /* convert to our meaning of end-of-stream */
else {
@@ -1452,7 +1464,11 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet
decoder_session->channels = metadata->data.stream_info.channels;
decoder_session->sample_rate = metadata->data.stream_info.sample_rate;
- flac__utils_canonicalize_skip_until_specification(decoder_session->skip_specification, decoder_session->sample_rate);
+ if(!flac__utils_canonicalize_skip_until_specification(decoder_session->skip_specification, decoder_session->sample_rate)) {
+ flac__utils_printf(stderr, 1, "%s: ERROR, value of --skip is too large\n", decoder_session->inbasefilename);
+ decoder_session->abort_flag = true;
+ return;
+ }
FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
@@ -1529,6 +1545,13 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet
return;
}
}
+ else if(decoder_session->bps == 0) {
+ flac__utils_printf(stderr, 1, "%s: WARNING: can't apply ReplayGain, bit-per-sample value is invalid\n", decoder_session->inbasefilename);
+ if(decoder_session->treat_warnings_as_errors) {
+ decoder_session->abort_flag = true;
+ return;
+ }
+ }
else {
const char *ls[] = { "no", "peak", "hard" };
const char *ns[] = { "no", "low", "medium", "high" };
diff --git a/src/flac/decode.h b/src/flac/decode.h
index 67bd3c04..24f5723d 100644
--- a/src/flac/decode.h
+++ b/src/flac/decode.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/flac/encode.c b/src/flac/encode.c
index bc71088d..a945b356 100644
--- a/src/flac/encode.c
+++ b/src/flac/encode.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -47,7 +47,6 @@
#endif
#define max(x,y) ((x)>(y)?(x):(y))
-/* this MUST be >= 588 so that sector aligning can take place with one read */
/* this MUST be < 2^sizeof(size_t) / ( FLAC__MAX_CHANNELS * (FLAC__MAX_BITS_PER_SAMPLE/8) ) */
#define CHUNK_OF_SAMPLES 2048
@@ -143,7 +142,7 @@ static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
*/
static FLAC__bool EncoderSession_construct(EncoderSession *e, encode_options_t options, FLAC__off_t infilesize, FILE *infile, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, uint32_t lookahead_length);
static void EncoderSession_destroy(EncoderSession *e);
-static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata, FLAC__bool error_on_compression_fail);
+static int EncoderSession_finish_ok(EncoderSession *e, foreign_metadata_t *foreign_metadata, FLAC__bool error_on_compression_fail);
static int EncoderSession_finish_error(EncoderSession *e);
static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options);
static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], uint32_t samples);
@@ -327,7 +326,7 @@ static FLAC__bool get_sample_info_wave(EncoderSession *e, encode_options_t optio
}
data_bytes -= (16+8);
}
- if(data_bytes < 16) {
+ if(data_bytes < 16 || data_bytes > (UINT32_MAX-8)) {
flac__utils_printf(stderr, 1, "%s: ERROR: non-standard 'fmt ' chunk has length = %u\n", e->inbasefilename, (uint32_t)data_bytes);
return false;
}
@@ -482,7 +481,6 @@ static FLAC__bool get_sample_info_wave(EncoderSession *e, encode_options_t optio
data_bytes = ds64_data_size;
}
if(options.ignore_chunk_sizes) {
- FLAC__ASSERT(!options.sector_align);
if(data_bytes) {
flac__utils_printf(stderr, 1, "%s: WARNING: 'data' chunk has non-zero size, using --ignore-chunk-sizes is probably a bad idea\n", e->inbasefilename, chunk_id);
if(e->treat_warnings_as_errors)
@@ -717,7 +715,6 @@ static FLAC__bool get_sample_info_aiff(EncoderSession *e, encode_options_t optio
return false;
data_bytes = xx;
if(options.ignore_chunk_sizes) {
- FLAC__ASSERT(!options.sector_align);
if(data_bytes) {
flac__utils_printf(stderr, 1, "%s: WARNING: 'SSND' chunk has non-zero size, using --ignore-chunk-sizes is probably a bad idea\n", e->inbasefilename, chunk_id);
if(e->treat_warnings_as_errors)
@@ -864,7 +861,6 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
{
EncoderSession encoder_session;
size_t channel_map[FLAC__MAX_CHANNELS];
- int info_align_carry = -1, info_align_zero = -1;
if(!EncoderSession_construct(&encoder_session, options, infilesize, infile, infilename, outfilename, lookahead, lookahead_length))
return 1;
@@ -946,34 +942,19 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
return EncoderSession_finish_error(&encoder_session);
}
- if(options.sector_align) {
- if(encoder_session.info.channels != 2) {
- flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, encoder_session.info.channels);
- return EncoderSession_finish_error(&encoder_session);
- }
- if(encoder_session.info.sample_rate != 44100) {
- flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, encoder_session.info.sample_rate);
- return EncoderSession_finish_error(&encoder_session);
- }
- if(encoder_session.info.bits_per_sample-encoder_session.info.shift != 16) {
- flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits-per-sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
- return EncoderSession_finish_error(&encoder_session);
- }
- }
{
FLAC__uint64 total_samples_in_input; /* WATCHOUT: may be 0 to mean "unknown" */
FLAC__uint64 skip;
FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
uint32_t consecutive_eos_count = 0;
- uint32_t align_remainder = 0;
switch(options.format) {
case FORMAT_RAW:
if(infilesize < 0)
total_samples_in_input = 0;
else
- total_samples_in_input = (FLAC__uint64)infilesize / encoder_session.info.bytes_per_wide_sample + *options.align_reservoir_samples;
+ total_samples_in_input = (FLAC__uint64)infilesize / encoder_session.info.bytes_per_wide_sample;
break;
case FORMAT_WAVE:
case FORMAT_WAVE64:
@@ -981,7 +962,7 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
case FORMAT_AIFF:
case FORMAT_AIFF_C:
/* truncation in the division removes any padding byte that was counted in encoder_session.fmt.iff.data_bytes */
- total_samples_in_input = encoder_session.fmt.iff.data_bytes / encoder_session.info.bytes_per_wide_sample + *options.align_reservoir_samples;
+ total_samples_in_input = encoder_session.fmt.iff.data_bytes / encoder_session.info.bytes_per_wide_sample;
/* check for chunks trailing the audio data */
if(!options.ignore_chunk_sizes && !options.format_options.iff.foreign_metadata
@@ -1004,7 +985,7 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
break;
case FORMAT_FLAC:
case FORMAT_OGGFLAC:
- total_samples_in_input = encoder_session.fmt.flac.client_data.metadata_blocks[0]->data.stream_info.total_samples + *options.align_reservoir_samples;
+ total_samples_in_input = encoder_session.fmt.flac.client_data.metadata_blocks[0]->data.stream_info.total_samples;
break;
default:
FLAC__ASSERT(0);
@@ -1016,12 +997,12 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
* now that we know the sample rate, canonicalize the
* --skip string to an absolute sample number:
*/
- flac__utils_canonicalize_skip_until_specification(&options.skip_specification, encoder_session.info.sample_rate);
+ if(!flac__utils_canonicalize_skip_until_specification(&options.skip_specification, encoder_session.info.sample_rate)) {
+ flac__utils_printf(stderr, 1, "%s: ERROR: value of --skip is too large\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
+ return EncoderSession_finish_error(&encoder_session);
+ }
FLAC__ASSERT(options.skip_specification.value.samples >= 0);
skip = (FLAC__uint64)options.skip_specification.value.samples;
- FLAC__ASSERT(!options.sector_align || (options.format != FORMAT_FLAC && options.format != FORMAT_OGGFLAC && skip == 0));
- /* *options.align_reservoir_samples will be 0 unless --sector-align is used */
- FLAC__ASSERT(options.sector_align || *options.align_reservoir_samples == 0);
/*
* now that we possibly know the input size, canonicalize the
@@ -1030,11 +1011,15 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
if(!canonicalize_until_specification(&options.until_specification, encoder_session.inbasefilename, encoder_session.info.sample_rate, skip, total_samples_in_input))
return EncoderSession_finish_error(&encoder_session);
until = (FLAC__uint64)options.until_specification.value.samples;
- FLAC__ASSERT(!options.sector_align || until == 0);
/* adjust encoding parameters based on skip and until values */
switch(options.format) {
case FORMAT_RAW:
+ FLAC__ASSERT(sizeof(FLAC__off_t) == 8);
+ if(skip >= INT64_MAX / encoder_session.info.bytes_per_wide_sample) {
+ flac__utils_printf(stderr, 1, "%s: ERROR: value of --skip is too large\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
+ return EncoderSession_finish_error(&encoder_session);
+ }
infilesize -= (FLAC__off_t)skip * encoder_session.info.bytes_per_wide_sample;
encoder_session.total_samples_to_encode = total_samples_in_input - skip;
break;
@@ -1043,6 +1028,11 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
case FORMAT_RF64:
case FORMAT_AIFF:
case FORMAT_AIFF_C:
+ FLAC__ASSERT(sizeof(FLAC__off_t) == 8);
+ if(skip >= INT64_MAX / encoder_session.info.bytes_per_wide_sample) {
+ flac__utils_printf(stderr, 1, "%s: ERROR: value of --skip is too large\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
+ return EncoderSession_finish_error(&encoder_session);
+ }
encoder_session.fmt.iff.data_bytes -= skip * encoder_session.info.bytes_per_wide_sample;
if(options.ignore_chunk_sizes) {
encoder_session.total_samples_to_encode = 0;
@@ -1064,21 +1054,12 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
if(until > 0) {
const FLAC__uint64 trim = total_samples_in_input - until;
FLAC__ASSERT(total_samples_in_input > 0);
- FLAC__ASSERT(!options.sector_align);
if(options.format == FORMAT_RAW)
infilesize -= (FLAC__off_t)trim * encoder_session.info.bytes_per_wide_sample;
else if(EncoderSession_format_is_iff(&encoder_session))
encoder_session.fmt.iff.data_bytes -= trim * encoder_session.info.bytes_per_wide_sample;
encoder_session.total_samples_to_encode -= trim;
}
- if(options.sector_align && (options.format != FORMAT_RAW || infilesize >=0)) { /* for RAW, need to know the filesize */
- FLAC__ASSERT(skip == 0); /* asserted above too, but lest we forget */
- align_remainder = (uint32_t)(encoder_session.total_samples_to_encode % 588);
- if(options.is_last_file)
- encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
- else
- encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
- }
switch(options.format) {
case FORMAT_RAW:
encoder_session.unencoded_size = encoder_session.total_samples_to_encode * encoder_session.info.bytes_per_wide_sample;
@@ -1183,36 +1164,6 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
}
/*
- * first do any samples in the reservoir
- */
- if(options.sector_align && *options.align_reservoir_samples > 0) {
- FLAC__ASSERT(options.format != FORMAT_FLAC && options.format != FORMAT_OGGFLAC); /* check again */
- if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.align_reservoir, *options.align_reservoir_samples)) {
- print_error_with_state(&encoder_session, "ERROR during encoding");
- return EncoderSession_finish_error(&encoder_session);
- }
- }
-
- /*
- * decrement infilesize or the data_bytes counter if we need to align the file
- */
- if(options.sector_align) {
- if(options.is_last_file) {
- *options.align_reservoir_samples = 0;
- }
- else {
- *options.align_reservoir_samples = align_remainder;
- if(options.format == FORMAT_RAW) {
- FLAC__ASSERT(infilesize >= 0);
- infilesize -= (FLAC__off_t)((*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample);
- FLAC__ASSERT(infilesize >= 0);
- }
- else if(EncoderSession_format_is_iff(&encoder_session))
- encoder_session.fmt.iff.data_bytes -= (*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample;
- }
- }
-
- /*
* now do samples from the file
*/
switch(options.format) {
@@ -1265,10 +1216,18 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
wanted = (size_t) min((FLAC__uint64)wanted, max_input_bytes - total_input_bytes_read);
if(lookahead_length > 0) {
- FLAC__ASSERT(lookahead_length <= wanted);
- memcpy(ubuffer.u8, lookahead, lookahead_length);
- wanted -= lookahead_length;
- bytes_read = lookahead_length;
+ if(lookahead_length <= wanted) {
+ memcpy(ubuffer.u8, lookahead, lookahead_length);
+ wanted -= lookahead_length;
+ bytes_read = lookahead_length;
+ }
+ else {
+ /* This happens when --until is used on a very short file */
+ FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * encoder_session.info.bytes_per_wide_sample);
+ memcpy(ubuffer.u8, lookahead, wanted);
+ wanted = 0;
+ bytes_read = wanted;
+ }
if(wanted > 0) {
bytes_read += fread(ubuffer.u8+lookahead_length, sizeof(uint8_t), wanted, infile);
if(ferror(infile)) {
@@ -1382,7 +1341,7 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
break;
}
- if(!FLAC__stream_decoder_process_single(encoder_session.fmt.flac.decoder)) {
+ if(decoder_state == FLAC__STREAM_DECODER_ABORTED || !FLAC__stream_decoder_process_single(encoder_session.fmt.flac.decoder)) {
flac__utils_printf(stderr, 1, "%s: ERROR: while decoding FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(encoder_session.fmt.flac.decoder));
return EncoderSession_finish_error(&encoder_session);
}
@@ -1398,53 +1357,10 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
return EncoderSession_finish_error(&encoder_session);
}
- /*
- * now read unaligned samples into reservoir or pad with zeroes if necessary
- */
- if(options.sector_align) {
- if(options.is_last_file) {
- uint32_t wide_samples = 588 - align_remainder;
- if(wide_samples < 588) {
- uint32_t channel;
-
- info_align_zero = wide_samples;
- for(channel = 0; channel < encoder_session.info.channels; channel++)
- memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
-
- if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
- print_error_with_state(&encoder_session, "ERROR during encoding");
- return EncoderSession_finish_error(&encoder_session);
- }
- }
- }
- else {
- if(*options.align_reservoir_samples > 0) {
- size_t bytes_read;
- FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
- bytes_read = fread(ubuffer.u8, sizeof(uint8_t), (*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample, infile);
- if(bytes_read == 0 && ferror(infile)) {
- flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
- return EncoderSession_finish_error(&encoder_session);
- }
- else if(bytes_read != (*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample) {
- flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %" PRIu64 " bytes; expected %" PRIu64 " samples, got %" PRIu64 " samples\n", encoder_session.inbasefilename, bytes_read, encoder_session.total_samples_to_encode, encoder_session.samples_written);
- if(encoder_session.treat_warnings_as_errors)
- return EncoderSession_finish_error(&encoder_session);
- }
- else {
- info_align_carry = *options.align_reservoir_samples;
- if(!format_input(options.align_reservoir, *options.align_reservoir_samples, encoder_session.info.is_big_endian, encoder_session.info.is_unsigned_samples, encoder_session.info.channels, encoder_session.info.bits_per_sample, encoder_session.info.shift, channel_map))
- return EncoderSession_finish_error(&encoder_session);
- }
- }
- }
- }
}
return EncoderSession_finish_ok(
&encoder_session,
- info_align_carry,
- info_align_zero,
EncoderSession_format_is_iff(&encoder_session)? options.format_options.iff.foreign_metadata : 0,
options.error_on_compression_fail
);
@@ -1520,7 +1436,9 @@ FLAC__bool EncoderSession_construct(EncoderSession *e, encode_options_t options,
e->fmt.flac.client_data.fatal_error = false;
break;
default:
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
FLAC__ASSERT(0);
+#endif
/* double protection */
return false;
}
@@ -1571,7 +1489,7 @@ void EncoderSession_destroy(EncoderSession *e)
}
}
-int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata, FLAC__bool error_on_compression_fail)
+int EncoderSession_finish_ok(EncoderSession *e, foreign_metadata_t *foreign_metadata, FLAC__bool error_on_compression_fail)
{
FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
int ret = 0;
@@ -1597,14 +1515,6 @@ int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_a
print_verify_error(e);
ret = 1;
}
- else {
- if(info_align_carry >= 0) {
- flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
- }
- if(info_align_zero >= 0) {
- flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
- }
- }
/*@@@@@@ should this go here or somewhere else? */
if(ret == 0 && foreign_metadata) {
@@ -1626,6 +1536,11 @@ int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_a
ret = 1;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /* Always delete output file when fuzzing */
+ flac_unlink(e->outfilename);
+#endif
+
EncoderSession_destroy(e);
return ret;
@@ -1951,8 +1866,12 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
flac_decoder_data->num_metadata_blocks = j;
if(options.padding > 0)
p = options.padding;
- if(p < 0)
- p = e->total_samples_to_encode / sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8;
+ if(p < 0) {
+ if(sample_rate == 0)
+ p = FLAC_ENCODE__DEFAULT_PADDING;
+ else
+ p = e->total_samples_to_encode / sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8;
+ }
if(p > 0)
p += (e->replay_gain ? GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED : 0);
p = min(p, (int)((1u << FLAC__STREAM_METADATA_LENGTH_LEN) - 1));
@@ -2015,7 +1934,10 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
if(options.padding != 0) {
padding.is_last = false; /* the encoder will set this for us */
padding.type = FLAC__METADATA_TYPE_PADDING;
- padding.length = (uint32_t)(options.padding>0? options.padding : (e->total_samples_to_encode / sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8)) + (e->replay_gain ? GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED : 0);
+ if(sample_rate == 0)
+ padding.length = (uint32_t)(options.padding>0? options.padding : FLAC_ENCODE__DEFAULT_PADDING) + (e->replay_gain ? GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED : 0);
+ else
+ padding.length = (uint32_t)(options.padding>0? options.padding : (e->total_samples_to_encode / sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8)) + (e->replay_gain ? GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED : 0);
padding.length = min(padding.length, (1u << FLAC__STREAM_METADATA_LENGTH_LEN) - 1);
static_metadata_append(&static_metadata, &padding, /*needs_delete=*/false);
}
@@ -2065,19 +1987,25 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
}
break;
case CST_MAX_LPC_ORDER:
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
FLAC__stream_encoder_set_max_lpc_order(e->encoder, options.compression_settings[ic].value.t_unsigned);
+#endif
break;
case CST_QLP_COEFF_PRECISION:
FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder, options.compression_settings[ic].value.t_unsigned);
break;
case CST_DO_QLP_COEFF_PREC_SEARCH:
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder, options.compression_settings[ic].value.t_bool);
+#endif
break;
case CST_DO_ESCAPE_CODING:
FLAC__stream_encoder_set_do_escape_coding(e->encoder, options.compression_settings[ic].value.t_bool);
break;
case CST_DO_EXHAUSTIVE_MODEL_SEARCH:
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder, options.compression_settings[ic].value.t_bool);
+#endif
break;
case CST_MIN_RESIDUAL_PARTITION_ORDER:
FLAC__stream_encoder_set_min_residual_partition_order(e->encoder, options.compression_settings[ic].value.t_unsigned);
@@ -2090,8 +2018,10 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
break;
}
}
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if(*apodizations)
FLAC__stream_encoder_set_apodization(e->encoder, apodizations);
+#endif
FLAC__stream_encoder_set_total_samples_estimate(e->encoder, e->total_samples_to_encode);
FLAC__stream_encoder_set_metadata(e->encoder, (num_metadata > 0)? metadata : 0, num_metadata);
FLAC__stream_encoder_set_limit_min_bitrate(e->encoder, options.limit_min_bitrate);
@@ -2180,14 +2110,13 @@ FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int
if(num_requested_seek_points == 0 && 0 == cuesheet)
return true;
- if(num_requested_seek_points < 0) {
#if FLAC__HAS_OGG
- /*@@@@@@ workaround ogg bug: too many seekpoints makes table not fit in one page */
- if(e->use_ogg && e->total_samples_to_encode > 0 && e->total_samples_to_encode / e->info.sample_rate / 10 > 230)
- requested_seek_points = "230x;";
- else
+ if(e->use_ogg)
+ return true;
#endif
- requested_seek_points = "10s;";
+
+ if(num_requested_seek_points < 0) {
+ requested_seek_points = "10s;";
num_requested_seek_points = 1;
}
@@ -2226,7 +2155,10 @@ FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int
FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, uint32_t sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
{
/* convert from mm:ss.sss to sample number if necessary */
- flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
+ if(!flac__utils_canonicalize_skip_until_specification(spec, sample_rate)) {
+ flac__utils_printf(stderr, 1, "%s: ERROR, value of --until is too large\n", inbasefilename);
+ return false;
+ }
/* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
if(spec->is_relative && spec->value.samples == 0) {
@@ -2390,7 +2322,7 @@ FLAC__bool format_input(FLAC__int32 *dest[], uint32_t wide_samples, FLAC__bool i
uint32_t t;
t = ubuffer.u8[b];
t |= (uint32_t)(ubuffer.u8[b+1]) << 8;
- t |= (int32_t)(ubuffer.s8[b+2]) << 16;
+ t |= (uint32_t)((int32_t)(ubuffer.s8[b+2])) << 16;
out[channel][wide_sample] = t;
b += 3*channels;
}
@@ -2876,7 +2808,7 @@ FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, const char *fn)
return false;
e = ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
shift = 63-e;
- if((buf[0]>>7)==1U || e<0 || e>63) {
+ if((buf[0]>>7)==1U || e<0 || e>=63) {
flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
return false;
}
diff --git a/src/flac/encode.h b/src/flac/encode.h
index 5cb2cb78..2d65c506 100644
--- a/src/flac/encode.h
+++ b/src/flac/encode.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -76,14 +76,10 @@ typedef struct {
FLAC__bool cued_seekpoints;
FLAC__bool channel_map_none; /* --channel-map=none specified, eventually will expand to take actual channel map */
- /* options related to --replay-gain and --sector-align */
FLAC__bool is_first_file;
FLAC__bool is_last_file;
- FLAC__int32 **align_reservoir;
- unsigned *align_reservoir_samples;
FLAC__bool replay_gain;
FLAC__bool ignore_chunk_sizes;
- FLAC__bool sector_align;
FLAC__bool error_on_compression_fail;
FLAC__bool limit_min_bitrate;
FLAC__bool relaxed_foreign_metadata_handling;
diff --git a/src/flac/foreign_metadata.c b/src/flac/foreign_metadata.c
index 63f982cc..f63fc3e6 100644
--- a/src/flac/foreign_metadata.c
+++ b/src/flac/foreign_metadata.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -99,7 +99,12 @@ static FLAC__bool compare_data_(FILE *fin, FILE *fout, size_t size, const char *
static FLAC__bool append_block_(foreign_metadata_t *fm, FLAC__off_t offset, FLAC__uint32 size, const char **error)
{
- foreign_block_t *fb = safe_realloc_nofree_muladd2_(fm->blocks, sizeof(foreign_block_t), /*times (*/fm->num_blocks, /*+*/1/*)*/);
+ foreign_block_t *fb;
+ if(size >= ((1u << FLAC__STREAM_METADATA_LENGTH_LEN) - FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)) {
+ if(error) *error = "found foreign metadata chunk is too large (max is 16MiB per chunk)";
+ return false;
+ }
+ fb = safe_realloc_nofree_muladd2_(fm->blocks, sizeof(foreign_block_t), /*times (*/fm->num_blocks, /*+*/1/*)*/);
if(fb) {
fb[fm->num_blocks].offset = offset;
fb[fm->num_blocks].size = size;
diff --git a/src/flac/foreign_metadata.h b/src/flac/foreign_metadata.h
index 83d8e81f..fa68d46f 100644
--- a/src/flac/foreign_metadata.h
+++ b/src/flac/foreign_metadata.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/flac/iffscan.c b/src/flac/iffscan.c
index 5b868fd1..a5472e0c 100644
--- a/src/flac/iffscan.c
+++ b/src/flac/iffscan.c
@@ -1,6 +1,6 @@
/* iffscan - Simple AIFF/RIFF chunk scanner
* Copyright (C) 2007-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/flac/local_string_utils.h b/src/flac/local_string_utils.h
index e869d701..01f891f7 100644
--- a/src/flac/local_string_utils.h
+++ b/src/flac/local_string_utils.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2002-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/flac/main.c b/src/flac/main.c
index 56c2dfc4..c22e602c 100644
--- a/src/flac/main.c
+++ b/src/flac/main.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2000-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -151,7 +151,6 @@ static struct share__option long_options_[] = {
{ "lax" , share__no_argument, 0, 0 },
{ "replay-gain" , share__no_argument, 0, 0 },
{ "ignore-chunk-sizes" , share__no_argument, 0, 0 },
- { "sector-align" , share__no_argument, 0, 0 }, /* DEPRECATED */
{ "seekpoint" , share__required_argument, 0, 'S' },
{ "padding" , share__required_argument, 0, 'P' },
#if FLAC__HAS_OGG
@@ -194,7 +193,6 @@ static struct share__option long_options_[] = {
{ "no-keep-foreign-metadata" , share__no_argument, 0, 0 },
{ "no-replay-gain" , share__no_argument, 0, 0 },
{ "no-ignore-chunk-sizes" , share__no_argument, 0, 0 },
- { "no-sector-align" , share__no_argument, 0, 0 }, /* DEPRECATED */
{ "no-utf8-convert" , share__no_argument, 0, 0 },
{ "no-lax" , share__no_argument, 0, 0 },
#if FLAC__HAS_OGG
@@ -257,7 +255,6 @@ static struct {
FLAC__bool keep_foreign_metadata_if_present;
FLAC__bool replay_gain;
FLAC__bool ignore_chunk_sizes;
- FLAC__bool sector_align;
FLAC__bool utf8_convert; /* true by default, to convert tag strings from locale to utf-8, false if --no-utf8-convert used */
const char *cmdline_forced_outfilename;
const char *output_prefix;
@@ -302,10 +299,6 @@ static struct {
* miscellaneous globals
*/
-static FLAC__int32 align_reservoir_0[588], align_reservoir_1[588]; /* for carrying over samples from --sector-align */ /* DEPRECATED */
-static FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 };
-static uint32_t align_reservoir_samples = 0; /* 0 .. 587 */
-
#ifndef FUZZ_TOOL_FLAC
int main(int argc, char *argv[])
@@ -441,8 +434,6 @@ int do_it(void)
if(option_values.ignore_chunk_sizes) {
if(option_values.mode_decode)
return usage_error("ERROR: --ignore-chunk-sizes only allowed for encoding\n");
- if(0 != option_values.sector_align)
- return usage_error("ERROR: --ignore-chunk-sizes not allowed with --sector-align\n");
if(0 != option_values.until_specification)
return usage_error("ERROR: --ignore-chunk-sizes not allowed with --until\n");
if(0 != option_values.cue_specification)
@@ -450,22 +441,6 @@ int do_it(void)
if(0 != option_values.cuesheet_filename)
return usage_error("ERROR: --ignore-chunk-sizes not allowed with --cuesheet\n");
}
- if(option_values.sector_align) {
- if(option_values.mode_decode)
- return usage_error("ERROR: --sector-align only allowed for encoding\n");
- if(0 != option_values.skip_specification)
- return usage_error("ERROR: --sector-align not allowed with --skip\n");
- if(0 != option_values.until_specification)
- return usage_error("ERROR: --sector-align not allowed with --until\n");
- if(0 != option_values.cue_specification)
- return usage_error("ERROR: --sector-align not allowed with --cue\n");
- if(option_values.format_channels >= 0 && option_values.format_channels != 2)
- return usage_error("ERROR: --sector-align can only be done with stereo input\n");
- if(option_values.format_bps >= 0 && option_values.format_bps != 16)
- return usage_error("ERROR: --sector-align can only be done with 16-bit samples\n");
- if(option_values.format_sample_rate >= 0 && option_values.format_sample_rate != 44100)
- return usage_error("ERROR: --sector-align can only be done with a sample rate of 44100\n");
- }
if(option_values.replay_gain) {
if(option_values.force_to_stdout)
return usage_error("ERROR: --replay-gain not allowed with -c/--stdout\n");
@@ -505,7 +480,7 @@ int do_it(void)
flac__utils_printf(stderr, 2, "\n");
flac__utils_printf(stderr, 2, "flac %s\n", FLAC__VERSION_STRING);
- flac__utils_printf(stderr, 2, "Copyright (C) 2000-2009 Josh Coalson, 2011-2022 Xiph.Org Foundation\n");
+ flac__utils_printf(stderr, 2, "Copyright (C) 2000-2009 Josh Coalson, 2011-2023 Xiph.Org Foundation\n");
flac__utils_printf(stderr, 2, "flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
flac__utils_printf(stderr, 2, "welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
@@ -543,8 +518,10 @@ int do_it(void)
for(i = 0, retval = 0; i < option_values.num_files; i++) {
if(0 == strcmp(option_values.filenames[i], "-") && !first)
continue;
- retval |= encode_file(option_values.filenames[i], first, i == (option_values.num_files-1));
- first = false;
+ if(encode_file(option_values.filenames[i], first, i == (option_values.num_files-1)))
+ retval = 1;
+ else
+ first = false;
}
if(option_values.replay_gain && retval == 0) {
float album_gain, album_peak;
@@ -571,6 +548,7 @@ FLAC__bool init_options(void)
{
option_values.show_help = false;
option_values.show_explain = false;
+ option_values.show_version = false;
option_values.mode_decode = false;
option_values.verify = false;
option_values.treat_warnings_as_errors = false;
@@ -602,7 +580,6 @@ FLAC__bool init_options(void)
option_values.keep_foreign_metadata_if_present = false;
option_values.replay_gain = false;
option_values.ignore_chunk_sizes = false;
- option_values.sector_align = false;
option_values.utf8_convert = true;
option_values.cmdline_forced_outfilename = 0;
option_values.output_prefix = 0;
@@ -821,11 +798,6 @@ int parse_option(int short_option, const char *long_option, const char *option_a
else if(0 == strcmp(long_option, "ignore-chunk-sizes")) {
option_values.ignore_chunk_sizes = true;
}
- else if(0 == strcmp(long_option, "sector-align")) {
- flac__utils_printf(stderr, 1, "WARNING: --sector-align is DEPRECATED and may not exist in future versions of flac.\n");
- flac__utils_printf(stderr, 1, " shntool provides similar functionality\n");
- option_values.sector_align = true;
- }
#if FLAC__HAS_OGG
else if(0 == strcmp(long_option, "ogg")) {
option_values.use_ogg = true;
@@ -908,9 +880,6 @@ int parse_option(int short_option, const char *long_option, const char *option_a
else if(0 == strcmp(long_option, "no-ignore-chunk-sizes")) {
option_values.ignore_chunk_sizes = false;
}
- else if(0 == strcmp(long_option, "no-sector-align")) {
- option_values.sector_align = false;
- }
else if(0 == strcmp(long_option, "no-utf8-convert")) {
option_values.utf8_convert = false;
}
@@ -1243,7 +1212,7 @@ static void usage_header(void)
printf("===============================================================================\n");
printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
printf("Copyright (C) 2000-2009 Josh Coalson\n");
- printf("Copyright (C) 2011-2022 Xiph.Org Foundation\n");
+ printf("Copyright (C) 2011-2023 Xiph.Org Foundation\n");
printf("\n");
printf("This program is free software; you can redistribute it and/or\n");
printf("modify it under the terms of the GNU General Public License\n");
@@ -1337,7 +1306,6 @@ void show_help(void)
printf(" -V, --verify Verify a correct encoding\n");
printf(" --lax Allow encoder to generate non-Subset files\n");
printf(" --ignore-chunk-sizes Ignore data chunk sizes in WAVE/AIFF files\n");
- printf(" --sector-align (DEPRECATED) Align multiple files on sector boundaries\n");
printf(" --replay-gain Calculate ReplayGain & store in FLAC tags\n");
printf(" --cuesheet=FILENAME Import cuesheet and store in CUESHEET block\n");
printf(" --picture=SPECIFICATION Import picture and store in PICTURE block\n");
@@ -1403,7 +1371,6 @@ void show_help(void)
printf(" --no-residual-gnuplot\n");
printf(" --no-residual-text\n");
printf(" --no-ignore-chunk-sizes\n");
- printf(" --no-sector-align\n");
printf(" --no-seektable\n");
printf(" --no-silent\n");
printf(" --no-force\n");
@@ -1546,10 +1513,6 @@ void show_explain(void)
printf(" --ignore-chunk-sizes Ignore data chunk sizes in WAVE/AIFF files;\n");
printf(" useful when piping data from programs which\n");
printf(" generate bogus data chunk sizes.\n");
- printf(" --sector-align Align encoding of multiple CD format WAVE files\n");
- printf(" on sector boundaries. This option is DEPRECATED\n");
- printf(" and may not exist in future versions of flac.\n");
- printf(" shntool offers similar functionality.\n");
printf(" --replay-gain Calculate ReplayGain values and store them as\n");
printf(" FLAC tags. Title gains/peaks will be computed\n");
printf(" for each file, and an album gain/peak will be\n");
@@ -1770,7 +1733,6 @@ void show_explain(void)
printf(" --no-residual-gnuplot\n");
printf(" --no-residual-text\n");
printf(" --no-ignore-chunk-sizes\n");
- printf(" --no-sector-align\n");
printf(" --no-seektable\n");
printf(" --no-silent\n");
printf(" --no-force\n");
@@ -1803,13 +1765,11 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
return 1;
}
-#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if(0 == strcmp(infilename, "-")) {
infilesize = (FLAC__off_t)(-1);
encode_infile = grabbag__file_get_binary_stdin();
}
else
-#endif
{
infilesize = grabbag__file_get_filesize(infilename);
if(0 == (encode_infile = flac_fopen(infilename, "rb"))) {
@@ -1963,17 +1923,6 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
}
}
- if(option_values.sector_align && (input_format == FORMAT_FLAC || input_format == FORMAT_OGGFLAC)) {
- flac__utils_printf(stderr, 1, "ERROR: can't use --sector-align when the input file is FLAC or Ogg FLAC\n");
- conditional_fclose(encode_infile);
- return 1;
- }
- if(option_values.sector_align && input_format == FORMAT_RAW && infilesize < 0) {
- flac__utils_printf(stderr, 1, "ERROR: can't use --sector-align when the input size is unknown\n");
- conditional_fclose(encode_infile);
- return 1;
- }
-
if(input_format == FORMAT_RAW) {
if(option_values.format_is_big_endian < 0 || option_values.format_is_unsigned_samples < 0 || option_values.format_channels < 0 || option_values.format_bps < 0 || option_values.format_sample_rate < 0) {
conditional_fclose(encode_infile);
@@ -2035,11 +1984,8 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
encode_options.channel_map_none = option_values.channel_map_none;
encode_options.is_first_file = is_first_file;
encode_options.is_last_file = is_last_file;
- encode_options.align_reservoir = align_reservoir;
- encode_options.align_reservoir_samples = &align_reservoir_samples;
encode_options.replay_gain = option_values.replay_gain;
encode_options.ignore_chunk_sizes = option_values.ignore_chunk_sizes;
- encode_options.sector_align = option_values.sector_align;
encode_options.vorbis_comment = option_values.vorbis_comment;
FLAC__ASSERT(sizeof(encode_options.pictures) >= sizeof(option_values.pictures));
memcpy(encode_options.pictures, option_values.pictures, sizeof(option_values.pictures));
@@ -2362,12 +2308,6 @@ int decode_file(const char *infilename)
decode_options.channel_map_none = option_values.channel_map_none;
decode_options.format = output_format;
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
- /* Can't fuzz from stdin */
- if(0 == strcmp(infilename, "-") || 0 == strcmp(outfilename, "-"))
- return 1;
-#endif
-
if(output_format == FORMAT_RAW) {
decode_options.format_options.raw.is_big_endian = option_values.format_is_big_endian;
decode_options.format_options.raw.is_unsigned_samples = option_values.format_is_unsigned_samples;
diff --git a/src/flac/utils.c b/src/flac/utils.c
index d236dc8e..446150d4 100644
--- a/src/flac/utils.c
+++ b/src/flac/utils.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2002-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -56,8 +56,18 @@ static FLAC__bool local__parse_uint64_(const char *s, FLAC__uint64 *value)
return false;
while('\0' != (c = *s++))
- if(c >= '0' && c <= '9')
- ret = ret * 10 + (c - '0');
+ if(c >= '0' && c <= '9') {
+ if(ret > UINT64_MAX / 10) /* check for overflow */
+ return false;
+ else if(ret == UINT64_MAX / 10) {
+ FLAC__uint64 tmp = ret;
+ ret = ret * 10 + (c - '0');
+ if(ret < tmp)
+ return false;
+ }
+ else
+ ret = ret * 10 + (c - '0');
+ }
else
return false;
@@ -300,6 +310,8 @@ FLAC__bool flac__utils_parse_skip_until_specification(const char *s, utils__Skip
if(local__parse_uint64_(s, &val)) {
spec->value_is_samples = true;
+ if(val > INT64_MAX)
+ return false;
spec->value.samples = (FLAC__int64)val;
if(is_negative)
spec->value.samples = -(spec->value.samples);
@@ -318,13 +330,17 @@ FLAC__bool flac__utils_parse_skip_until_specification(const char *s, utils__Skip
return true;
}
-void flac__utils_canonicalize_skip_until_specification(utils__SkipUntilSpecification *spec, uint32_t sample_rate)
+FLAC__bool flac__utils_canonicalize_skip_until_specification(utils__SkipUntilSpecification *spec, uint32_t sample_rate)
{
FLAC__ASSERT(0 != spec);
if(!spec->value_is_samples) {
- spec->value.samples = (FLAC__int64)(spec->value.seconds * (double)sample_rate);
+ double samples = spec->value.seconds * (double)sample_rate;
+ if(samples >= (double)INT64_MAX || samples <= (double)INT64_MIN)
+ return false;
+ spec->value.samples = (FLAC__int64)(samples);
spec->value_is_samples = true;
}
+ return true;
}
FLAC__bool flac__utils_parse_cue_specification(const char *s, utils__CueSpecification *spec)
diff --git a/src/flac/utils.h b/src/flac/utils.h
index 2c1f1536..931b4a6e 100644
--- a/src/flac/utils.h
+++ b/src/flac/utils.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2002-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -66,7 +66,7 @@ void stats_print_name(int level, const char *name);
void stats_print_info(int level, const char *format, ...);
FLAC__bool flac__utils_parse_skip_until_specification(const char *s, utils__SkipUntilSpecification *spec);
-void flac__utils_canonicalize_skip_until_specification(utils__SkipUntilSpecification *spec, uint32_t sample_rate);
+FLAC__bool flac__utils_canonicalize_skip_until_specification(utils__SkipUntilSpecification *spec, uint32_t sample_rate);
FLAC__bool flac__utils_parse_cue_specification(const char *s, utils__CueSpecification *spec);
void flac__utils_canonicalize_cue_specification(const utils__CueSpecification *cue_spec, const FLAC__StreamMetadata_CueSheet *cuesheet, FLAC__uint64 total_samples, utils__SkipUntilSpecification *skip_spec, utils__SkipUntilSpecification *until_spec);
diff --git a/src/flac/version.rc b/src/flac/version.rc
new file mode 100644
index 00000000..00842b92
--- /dev/null
+++ b/src/flac/version.rc
@@ -0,0 +1,38 @@
+#include <winver.h>
+#include "config.h"
+
+#if (defined GIT_COMMIT_HASH && defined GIT_COMMIT_DATE)
+# ifdef GIT_COMMIT_TAG
+# define VERSIONSTRING GIT_COMMIT_TAG
+# else
+# define VERSIONSTRING "git-" GIT_COMMIT_HASH
+# endif
+#else
+# define VERSIONSTRING PACKAGE_VERSION
+#endif
+
+#define xstr(s) str(s)
+#define str(s) #s
+
+VS_VERSION_INFO VERSIONINFO
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEFLAGS 0
+FILEOS VOS__WINDOWS32
+FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "flac command line tool for Windows"
+ VALUE "ProductName", "Free Lossless Audio Codec"
+ VALUE "ProductVersion", VERSIONSTRING
+ VALUE "CompanyName", "Xiph.Org"
+ VALUE "LegalCopyright", "2000-2009 Josh Coalson, 2011-2023 Xiph.Org Foundation"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/flac/vorbiscomment.c b/src/flac/vorbiscomment.c
index 434b5202..3941ec24 100644
--- a/src/flac/vorbiscomment.c
+++ b/src/flac/vorbiscomment.c
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2002-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/flac/vorbiscomment.h b/src/flac/vorbiscomment.h
index 6da6452d..a6dcb164 100644
--- a/src/flac/vorbiscomment.h
+++ b/src/flac/vorbiscomment.h
@@ -1,6 +1,6 @@
/* flac - Command-line FLAC encoder/decoder
* Copyright (C) 2002-2009 Josh Coalson
- * Copyright (C) 2011-2022 Xiph.Org Foundation
+ * Copyright (C) 2011-2023 Xiph.Org Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License