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());