COMMON: Add proper error handling to the ZipArchive class
- Add check in listMembers and skip files that can't be enumerated. - Add checks for all function calls in createReadStreamForMember (and no longer return a stream from an uninitialized buffer when the file cannot be read).
This commit is contained in:
parent
ea9774f689
commit
55650f364c
1 changed files with 25 additions and 10 deletions
|
@ -1470,11 +1470,13 @@ int ZipArchive::listMembers(Common::ArchiveMemberList &list) {
|
||||||
|
|
||||||
while (err == UNZ_OK) {
|
while (err == UNZ_OK) {
|
||||||
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
|
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
|
||||||
unzGetCurrentFileInfo(_zipFile, NULL,
|
if (unzGetCurrentFileInfo(_zipFile, NULL,
|
||||||
szCurrentFileName, sizeof(szCurrentFileName)-1,
|
szCurrentFileName, sizeof(szCurrentFileName)-1,
|
||||||
NULL, 0, NULL, 0);
|
NULL, 0, NULL, 0) == UNZ_OK) {
|
||||||
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(szCurrentFileName, this)));
|
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(szCurrentFileName, this)));
|
||||||
matches++;
|
matches++;
|
||||||
|
}
|
||||||
|
|
||||||
err = unzGoToNextFile(_zipFile);
|
err = unzGoToNextFile(_zipFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1493,18 +1495,31 @@ Common::SeekableReadStream *ZipArchive::createReadStreamForMember(const Common::
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unz_file_info fileInfo;
|
unz_file_info fileInfo;
|
||||||
unzOpenCurrentFile(_zipFile);
|
if (unzOpenCurrentFile(_zipFile) != UNZ_OK)
|
||||||
unzGetCurrentFileInfo(_zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
|
return 0;
|
||||||
|
|
||||||
|
if (unzGetCurrentFileInfo(_zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0) != UNZ_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
byte *buffer = (byte *)malloc(fileInfo.uncompressed_size);
|
byte *buffer = (byte *)malloc(fileInfo.uncompressed_size);
|
||||||
assert(buffer);
|
assert(buffer);
|
||||||
unzReadCurrentFile(_zipFile, buffer, fileInfo.uncompressed_size);
|
|
||||||
unzCloseCurrentFile(_zipFile);
|
if (unzReadCurrentFile(_zipFile, buffer, fileInfo.uncompressed_size) != (int)fileInfo.uncompressed_size) {
|
||||||
|
free(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unzCloseCurrentFile(_zipFile) != UNZ_OK) {
|
||||||
|
free(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size, DisposeAfterUse::YES);
|
return new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size, DisposeAfterUse::YES);
|
||||||
|
|
||||||
// FIXME: instead of reading all into a memory stream, we could
|
// FIXME: instead of reading all into a memory stream, we could
|
||||||
// instead create a new ZipStream class. But then we have to be
|
// instead create a new ZipStream class. But then we have to be
|
||||||
// careful to handle the case where the client code opens multiple
|
// careful to handle the case where the client code opens multiple
|
||||||
// files in the archive and tries to use them indepenendtly.
|
// files in the archive and tries to use them independently.
|
||||||
}
|
}
|
||||||
|
|
||||||
Archive *makeZipArchive(const String &name) {
|
Archive *makeZipArchive(const String &name) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue