Added a lot of checks to read slightly broken AVI files, as those created by Pinnacle Studio 9 for Windows, without problems.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9654 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2004-10-29 20:22:23 +00:00
parent 6f5f688cde
commit 84f1c37fc5

View File

@ -133,12 +133,21 @@ OpenDMLParser::Parse(BPositionIO *source)
uint32 temp;
uint32 fourcc;
uint32 size;
uint64 maxsize;
maxsize = fSize - pos;
if (maxsize < 13) {
ERROR("OpenDMLParser::Parse: remaining size too small for RIFF AVI chunk data at pos %lld\n", pos);
return false;
}
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
ERROR("OpenDMLParser::Parse: read error at pos %llu\n", pos);
return false;
}
pos += 4;
maxsize -= 4;
fourcc = AVI_UINT32(temp);
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
@ -146,12 +155,21 @@ OpenDMLParser::Parse(BPositionIO *source)
return false;
}
pos += 4;
maxsize -= 4;
size = AVI_UINT32(temp);
if (size == 0) {
ERROR("OpenDMLParser::Parse: Error: chunk of size 0 found\n");
return false;
}
TRACE("OpenDMLParser::Parse: chunk '"FOURCC_FORMAT"', size = %lu, maxsize %Ld\n", FOURCC_PARAM(fourcc), size, maxsize);
if (size > maxsize) {
ERROR("OpenDMLParser::Parse: Warning chunk '"FOURCC_FORMAT"', size = %lu extends beyond end of file\n", FOURCC_PARAM(fourcc), size);
ERROR("OpenDMLParser::Parse: Chunk at filepos %Ld truncated to %Ld, filesize %Ld\n", pos - 8, maxsize, fSize);
size = maxsize;
}
if (fourcc == FOURCC('J','U','N','K')) {
ERROR("OpenDMLParser::Parse: JUNK chunk ignored, size: %lu bytes\n", size);
@ -163,13 +181,13 @@ OpenDMLParser::Parse(BPositionIO *source)
ERROR("OpenDMLParser::Parse: not a RIFF file\n");
return false;
} else {
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' (expected 'RIFF'), size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' (expected 'RIFF'), size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
goto cont;
}
}
TRACE("OpenDMLParser::Parse: RIFF chunk %d size: %lu bytes\n", riff_chunk_number, size);
TRACE("OpenDMLParser::Parse: it's a RIFF chunk!\n");
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
ERROR("OpenDMLParser::Parse: read error at pos %llu\n", pos);
@ -183,7 +201,7 @@ OpenDMLParser::Parse(BPositionIO *source)
}
if (fourcc != FOURCC('A','V','I',' ') && fourcc != FOURCC('A','V','I','X')) {
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' , size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
TRACE("OpenDMLParser::Parse: unknown RIFF subchunk '"FOURCC_FORMAT"' , size = %lu ignored, filepos %Ld, filesize %Ld\n", FOURCC_PARAM(fourcc), size, pos - 8, fSize);
goto cont;
}
@ -203,7 +221,12 @@ OpenDMLParser::ParseChunk_AVI(int number, uint64 start, uint32 size)
TRACE("OpenDMLParser::ParseChunk_AVI\n");
uint64 pos = start;
uint64 end = start + size;
if (size < 9) {
ERROR("OpenDMLParser::ParseChunk_AVI: chunk is to small at pos %llu\n", start);
return false;
}
while (pos < end) {
uint32 temp;
uint32 Chunkfcc;
@ -223,13 +246,20 @@ OpenDMLParser::ParseChunk_AVI(int number, uint64 start, uint32 size)
pos += 4;
Chunksize = AVI_UINT32(temp);
TRACE("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"', size = %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize);
uint32 maxsize = end - pos;
TRACE("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"', size = %lu, maxsize %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize, maxsize);
if (Chunksize == 0) {
ERROR("OpenDMLParser::ParseChunk_AVI: Error: chunk of size 0 found\n");
ERROR("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"' has size 0\n", FOURCC_PARAM(Chunkfcc));
return false;
}
if (Chunksize > maxsize) {
TRACE("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"', size = %lu too big, truncated to %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize, maxsize);
Chunksize = maxsize;
}
if (Chunkfcc == FOURCC('L','I','S','T')) {
if (!ParseChunk_LIST(pos, Chunksize))
return false;
@ -254,6 +284,11 @@ OpenDMLParser::ParseChunk_LIST(uint64 start, uint32 size)
TRACE("OpenDMLParser::ParseChunk_LIST\n");
uint32 temp;
uint32 fourcc;
if (size < 5) {
ERROR("OpenDMLParser::ParseChunk_LIST: chunk is to small at pos %llu\n", start);
return false;
}
if (sizeof(temp) != fSource->ReadAt(start, &temp, sizeof(temp))) {
ERROR("OpenDMLParser::ParseChunk_LIST: read error at pos %llu\n", start);
@ -581,7 +616,7 @@ OpenDMLParser::ParseChunk_dmlh(uint64 start, uint32 size)
fOdmlExtendedHeaderValid = true;
TRACE("fOdmlExtendedHeader:\n");
TRACE("total_frames = %ld\n", fOdmlExtendedHeader.total_frames);
TRACE("total_frames = %lu\n", fOdmlExtendedHeader.total_frames);
return true;
}
@ -604,6 +639,11 @@ OpenDMLParser::ParseList_generic(uint64 start, uint32 size)
uint64 pos = start;
uint64 end = start + size;
if (size < 9) {
ERROR("OpenDMLParser::ParseList_generic: list too small at pos %llu\n",pos);
return false;
}
while (pos < end) {
uint32 temp;
uint32 Chunkfcc;
@ -622,14 +662,21 @@ OpenDMLParser::ParseList_generic(uint64 start, uint32 size)
}
pos += 4;
Chunksize = AVI_UINT32(temp);
uint32 maxsize = end - pos;
TRACE("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"', size = %ld\n", FOURCC_PARAM(Chunkfcc), Chunksize);
TRACE("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"', size = %lu, maxsize = %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize, maxsize);
if (Chunksize == 0) {
ERROR("OpenDMLParser::ParseList_generic: Error: chunk of size 0 found\n");
ERROR("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"' has size 0\n", FOURCC_PARAM(Chunkfcc));
return false;
}
if (Chunksize > maxsize) {
TRACE("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"', size = %lu too big, truncated to %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize, maxsize);
Chunksize = maxsize;
}
if (Chunkfcc == FOURCC('a','v','i','h')) {
if (!ParseChunk_avih(pos, Chunksize))
return false;