summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libFLAC/stream_encoder.c4
-rw-r--r--src/libFLAC/stream_encoder_framing.c10
-rwxr-xr-xtest/test_flac.sh23
3 files changed, 33 insertions, 4 deletions
diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
index d2574de7..8152e33e 100644
--- a/src/libFLAC/stream_encoder.c
+++ b/src/libFLAC/stream_encoder.c
@@ -2754,7 +2754,7 @@ void update_metadata_(const FLAC__StreamEncoder *encoder)
{
FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
- const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
+ FLAC__uint64 samples = metadata->data.stream_info.total_samples;
const uint32_t min_framesize = metadata->data.stream_info.min_framesize;
const uint32_t max_framesize = metadata->data.stream_info.max_framesize;
const uint32_t bps = metadata->data.stream_info.bits_per_sample;
@@ -2811,6 +2811,8 @@ void update_metadata_(const FLAC__StreamEncoder *encoder)
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
- 4
) / 8;
+ if(samples > (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
+ samples = 0;
b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c
index 828eb0e7..49b35d3b 100644
--- a/src/libFLAC/stream_encoder_framing.c
+++ b/src/libFLAC/stream_encoder_framing.c
@@ -96,9 +96,13 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__
FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN));
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN))
return false;
- FLAC__ASSERT(metadata->data.stream_info.total_samples < (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN));
- if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
- return false;
+ if(metadata->data.stream_info.total_samples >= (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)){
+ if(!FLAC__bitwriter_write_raw_uint64(bw, 0, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
+ return false;
+ }else{
+ if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
+ return false;
+ }
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16))
return false;
break;
diff --git a/test/test_flac.sh b/test/test_flac.sh
index cd17b164..369d23b4 100755
--- a/test/test_flac.sh
+++ b/test/test_flac.sh
@@ -1249,6 +1249,29 @@ flac2flac input-SCVA.flac case04e "--no-padding -S 5x"
# case 04f: on file with SEEKTABLE block and size-changing option specified, drop existing SEEKTABLE, new SEEKTABLE with default points
#(already covered by case03c)
+test_total_samples_overflow ()
+{
+ total_samples=$1
+ expected_stored_total_samples=$2
+ echo $ECHO_N "total_samples overflow test (samples=$total_samples) encode... " $ECHO_C
+ head -c $total_samples /dev/zero | run_flac --force --verify --sign=signed --sample-rate=96000 -b 16384 --channels=1 --endian=little --bps=8 -o big-$total_samples.flac - || die "ERROR"
+ echo $ECHO_N "decode... " $ECHO_C
+ run_flac -t big-$total_samples.flac || die "ERROR"
+ echo $ECHO_N "check... " $ECHO_C
+ run_metaflac --show-total-samples big-$total_samples.flac > big-$total_samples.cmp1
+ echo $expected_stored_total_samples > big-$total_samples.cmp2
+ diff -q -w big-$total_samples.cmp1 big-$total_samples.cmp2 || die "ERROR"
+ echo "OK"
+ rm -f big-$total_samples.flac big-$total_samples.cmp1 big-$total_samples.cmp2
+}
+
+if [ "$FLAC__TEST_LEVEL" -gt 1 ] ; then
+ test_total_samples_overflow 68719476735 68719476735
+ test_total_samples_overflow 68719476736 0
+ test_total_samples_overflow 68719476737 0
+fi
+
+
rm -f out.flac out.meta out1.meta
#@@@ when metaflac handles ogg flac, duplicate flac2flac tests here