From b4a1f3d7d11aa8a3c8218d9826848e9247c3ffc3 Mon Sep 17 00:00:00 2001 From: manuaudio Date: Sat, 15 Aug 2026 09:00:25 -0700 Subject: [PATCH] APE: do not convert out of range properties to int The frame count is assembled from three 32 bit header fields and the sample rate is read straight from the header, so a file can declare ~4.3e9 frames at 1 Hz. The millisecond length is then ~4.3e12 and the conversion to int is undefined: taglib/ape/apeproperties.cpp:141:35: runtime error: 4.29497e+12 is outside the range of representable values of type 'int' The bitrate on the next line is reachable the other way round, with one frame at a high declared rate making the divisor tiny: taglib/ape/apeproperties.cpp:142:35: runtime error: 3.60301e+13 is outside the range of representable values of type 'int' Leave the field at its default rather than converting. Two reports before the change, none after. The 23 FLAC, APE, Ogg Vorbis, Opus and Speex files in tests/data report identical channels, sample rate, bitrate and length before and after, and the suite runs 576 tests either way. Assisted-By: Claude Code (Claude Opus 5) --- taglib/ape/apeproperties.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/taglib/ape/apeproperties.cpp b/taglib/ape/apeproperties.cpp index 84d07628..f9f3d8bd 100644 --- a/taglib/ape/apeproperties.cpp +++ b/taglib/ape/apeproperties.cpp @@ -29,6 +29,8 @@ #include "apeproperties.h" +#include + #include "tdebug.h" #include "apefile.h" #include "apefooter.h" @@ -136,10 +138,19 @@ void APE::Properties::read(File *file, offset_t streamLength) else analyzeOld(file); + // Both the frame count and the sample rate are read from the file, so the + // millisecond length can land outside int, and a short stream at a high rate + // does the same to the bitrate. Converting a double the destination type + // cannot represent is undefined, so leave the field at its default instead. if(d->sampleFrames > 0 && d->sampleRate > 0) { const auto length = static_cast(d->sampleFrames) * 1000.0 / d->sampleRate; - d->length = static_cast(length + 0.5); - d->bitrate = static_cast(static_cast(streamLength) * 8.0 / length + 0.5); + if(length > 0.0 && length < static_cast(std::numeric_limits::max())) { + d->length = static_cast(length + 0.5); + + const double bitrate = static_cast(streamLength) * 8.0 / length; + if(bitrate >= 0.0 && bitrate < static_cast(std::numeric_limits::max())) + d->bitrate = static_cast(bitrate + 0.5); + } } }