From d6a2134cf3af577ee63130d400c433cb74cd8694 Mon Sep 17 00:00:00 2001 From: Ryan Francesconi <2917795+ryanfrancesconi@users.noreply.github.com> Date: Sat, 4 Apr 2026 03:47:49 -0700 Subject: [PATCH] Clamp oversized RIFF chunk to available bytes instead of rejecting it (#1329) Some encoders write a valid data chunk but with a slightly too-large declared chunkSize, or place the data chunk beyond the declared RIFF boundary. The previous behaviour called break, abandoning all remaining chunks and making the file appear empty to taglib. Lenient parsers (ffmpeg, QuickTime) handle this case by clamping the chunk size to the bytes that actually remain in the file. Adopt the same strategy: when chunkSize would exceed the file length, clamp it and continue parsing rather than stopping early. --- taglib/riff/rifffile.cpp | 10 +++++++--- tests/test_wav.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/taglib/riff/rifffile.cpp b/taglib/riff/rifffile.cpp index 66aa05e9..2594c1a3 100644 --- a/taglib/riff/rifffile.cpp +++ b/taglib/riff/rifffile.cpp @@ -298,7 +298,7 @@ void RIFF::File::read() seek(offset); const ByteVector chnkName = readBlock(4); - const unsigned int chunkSize = readBlock(4).toUInt(bigEndian); + unsigned int chunkSize = readBlock(4).toUInt(bigEndian); if(!isValidChunkName(chnkName)) { debug("RIFF::File::read() -- Chunk '" + chnkName + "' has invalid ID"); @@ -306,8 +306,12 @@ void RIFF::File::read() } if(static_cast(offset) + 8 + chunkSize > length()) { - debug("RIFF::File::read() -- Chunk '" + chnkName + "' has invalid size (larger than the file size)"); - break; + // Clamp to available bytes rather than rejecting the chunk outright. + // Some encoders write a correct data chunk but with a slightly too-large + // declared size, or place the data chunk outside the declared RIFF boundary. + // Lenient parsers (ffmpeg, QuickTime) handle this by clamping; we do the same. + debug("RIFF::File::read() -- Chunk '" + chnkName + "' is truncated; clamping size to available bytes."); + chunkSize = static_cast(length() - offset - 8); } Chunk chunk; diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index 5782a3c7..ea2f8e20 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -320,7 +320,7 @@ public: { FileStream stream(copy.fileName().c_str()); stream.seek(0, IOStream::End); - constexpr char garbage[] = "12345678"; + constexpr char garbage[] = "\r2345678"; stream.writeBlock(ByteVector(garbage, sizeof(garbage) - 1)); stream.seek(0); contentsBeforeModification = stream.readBlock(stream.length());