mirror of
https://github.com/taglib/taglib.git
synced 2026-04-12 17:09:50 -04:00
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.
This commit is contained in:
@ -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<long long>(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<unsigned int>(length() - offset - 8);
|
||||
}
|
||||
|
||||
Chunk chunk;
|
||||
|
||||
@ -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());
|
||||
|
||||
Reference in New Issue
Block a user