mirror of
https://github.com/taglib/taglib.git
synced 2026-08-27 12:47:01 -04:00
Resolve QuickTime chunk tables linearly (#1428)
A QuickTime chapter track can provide large stco and stsc tables. QtChapterList::resolveSampleOffsets() currently walks every stsc entry for every chunk, so a file with N entries can force O(N²) work during MP4::File::qtChapters(). A 3.2 MB file with 200,000 entries took about 20 seconds in the release build. Keep a cursor into stscEntries and advance it as chunk numbers increase. This resolves the same ordered table in linear time while avoiding attacker-controlled repeated scans.
This commit is contained in:
@@ -943,19 +943,15 @@ namespace
|
||||
std::vector<unsigned int> sampleOffsets;
|
||||
const auto totalChunks = static_cast<unsigned int>(chunkOffsets.size());
|
||||
unsigned int sampleIndex = 0;
|
||||
std::size_t stscIndex = 0;
|
||||
|
||||
for(unsigned int chunkIdx = 0; chunkIdx < totalChunks; ++chunkIdx) {
|
||||
// Find which stsc entry applies to this chunk (1-based)
|
||||
const unsigned int chunkNum = chunkIdx + 1;
|
||||
unsigned int samplesInChunk = stscEntries[0].samplesPerChunk;
|
||||
for(const auto & stscEntry : stscEntries) {
|
||||
if(stscEntry.firstChunk <= chunkNum) {
|
||||
samplesInChunk = stscEntry.samplesPerChunk;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(stscIndex + 1 < stscEntries.size() &&
|
||||
stscEntries[stscIndex + 1].firstChunk <= chunkNum)
|
||||
++stscIndex;
|
||||
unsigned int samplesInChunk = stscEntries[stscIndex].samplesPerChunk;
|
||||
|
||||
unsigned int offsetInChunk = 0;
|
||||
if(samplesInChunk > sizeInfo.sampleCount - sampleIndex)
|
||||
|
||||
Reference in New Issue
Block a user