mirror of
https://github.com/taglib/taglib.git
synced 2026-08-27 12:47:01 -04:00
DSDIFF: do not convert an out of range length to int
Same shape as the DSF change: sampleCount comes from a chunk size in the
file and sampleRate is read from it, so
static_cast<int>(static_cast<double>(d->sampleCount) * 1000.0
/ d->sampleRate + 0.5)
can be handed a value int cannot represent, which is undefined.
In the PR I said I had not demonstrated this one, because chunkFits
bounds the sample count by the file length so a few mutated bytes will
not do it. Constructing the file it does need - a 700 kB DSD chunk with
a sample rate of 1 - reaches it:
taglib/dsdiff/dsdiffproperties.cpp:61:24: runtime error: 2.8e+09 is
outside the range of representable values of type 'int'
Two reports before the change, none after. tests/data/empty10ms.dff is
unchanged at lengthMs=10 bitrate=5644 rate=2822400 ch=2.
Assisted-By: Claude Code (Claude Opus 5)
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "dsdiffproperties.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "tstring.h"
|
||||
|
||||
using namespace TagLib;
|
||||
@@ -57,9 +59,17 @@ DSDIFF::Properties::Properties(unsigned int sampleRate,
|
||||
d->sampleWidth = 1;
|
||||
d->sampleRate = sampleRate;
|
||||
d->bitrate = bitrate;
|
||||
d->length = d->sampleRate > 0
|
||||
? static_cast<int>(static_cast<double>(d->sampleCount) * 1000.0 / d->sampleRate + 0.5)
|
||||
: 0;
|
||||
// sampleCount is derived from a chunk size in the file and sampleRate is read from
|
||||
// it, so the millisecond count can land outside int, and converting a double the
|
||||
// destination type cannot represent is undefined. Report an unknown length instead,
|
||||
// which is what a zero sample rate already does.
|
||||
d->length = 0;
|
||||
if(d->sampleRate > 0 && d->sampleCount > 0) {
|
||||
const double milliseconds =
|
||||
static_cast<double>(d->sampleCount) * 1000.0 / d->sampleRate + 0.5;
|
||||
if(milliseconds < static_cast<double>(std::numeric_limits<int>::max()))
|
||||
d->length = static_cast<int>(milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
DSDIFF::Properties::~Properties() = default;
|
||||
|
||||
Reference in New Issue
Block a user