Fix overflow of streaminfo total samples (github issue 237)
When writing a FLAC file with over 2^36 samples, the total samples entry in streaminfo will overflow and wrap around. Setting it to 0 (which means unknown number of samples) makes sure the decoder doesn't rely on this number Co-authored-by: Ralph Giles <giles@thaumas.net>
This commit is contained in:
parent
7406eabe17
commit
7385dac383
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user