mirror of
https://github.com/taglib/taglib.git
synced 2026-08-27 12:47:01 -04:00
DSF: do not convert an out of range length to unsigned int
DSF::Properties::read computes
d->length = d->samplingFrequency > 0
? static_cast<unsigned int>(static_cast<double>(d->sampleCount)
* 1000.0 / d->samplingFrequency + 0.5)
: 0;
sampleCount is a long long taken straight from the file and
samplingFrequency is an unsigned int from the file, so the millisecond
count can land well outside unsigned int. Converting a floating point
value the destination type cannot represent is undefined:
taglib/dsf/dsfproperties.cpp:132:35: runtime error: 8.41595e+09 is
outside the range of representable values of type 'unsigned int'
#0 TagLib::DSF::Properties::read(TagLib::ByteVector const&)
#1 TagLib::DSF::Properties::Properties(...)
#10 TagLib::FileRef::FileRef(char const*, bool, ...)
A negative sampleCount converts just as badly, so guard that too.
Report an unknown length instead of converting, matching what a zero
sampling frequency already does. Nothing changes for a valid file:
tests/data/empty10ms.dsf reads lengthMs=10 bitrate=5645 rate=2822400
ch=2 both before and after.
Found by mutating the files in tests/data and running them through a
parse, read properties and save round trip under UBSan.
Assisted-By: Claude Code (Claude Opus 5)
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "dsfproperties.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class DSF::Properties::PropertiesPrivate
|
||||
@@ -128,7 +130,16 @@ void DSF::Properties::read(const ByteVector &data)
|
||||
|
||||
d->bitrate = static_cast<unsigned int>(
|
||||
d->samplingFrequency * d->bitsPerSample * d->channelNum / 1000.0 + 0.5);
|
||||
d->length = d->samplingFrequency > 0
|
||||
? static_cast<unsigned int>(static_cast<double>(d->sampleCount) * 1000.0 / d->samplingFrequency + 0.5)
|
||||
: 0;
|
||||
|
||||
// sampleCount and samplingFrequency both come straight from the file, so the
|
||||
// millisecond count can land outside unsigned int, and converting a double that
|
||||
// does not fit the destination type is undefined. Report an unknown length rather
|
||||
// than converting, which is what a zero sampling frequency already does.
|
||||
d->length = 0;
|
||||
if(d->samplingFrequency > 0 && d->sampleCount > 0) {
|
||||
const double milliseconds =
|
||||
static_cast<double>(d->sampleCount) * 1000.0 / d->samplingFrequency + 0.5;
|
||||
if(milliseconds < static_cast<double>(std::numeric_limits<unsigned int>::max()))
|
||||
d->length = static_cast<unsigned int>(milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user