Fix lockup on ZIP files containing errors (fixes #871).

This commit is contained in:
Stephen Anthony 2022-03-05 18:47:12 -03:30
parent 24e491bcde
commit 74b9eb2f73
2 changed files with 30 additions and 10 deletions

View File

@ -39,7 +39,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
if (_zipFile[0] == '~') if (_zipFile[0] == '~')
{ {
#if defined(BSPF_UNIX) || defined(BSPF_MACOS) #if defined(BSPF_UNIX) || defined(BSPF_MACOS)
string home = BSPF::getenv("HOME"); const string& home = BSPF::getenv("HOME");
if (home != EmptyString) if (home != EmptyString)
_zipFile.replace(0, 1, home); _zipFile.replace(0, 1, home);
#elif defined(BSPF_WINDOWS) #elif defined(BSPF_WINDOWS)
@ -71,6 +71,9 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
_virtualPath = p.substr(pos+5); _virtualPath = p.substr(pos+5);
_isFile = Bankswitch::isValidRomName(_virtualPath); _isFile = Bankswitch::isValidRomName(_virtualPath);
_isDirectory = !_isFile; _isDirectory = !_isFile;
// cerr << _virtualPath << ", isfile: " << _isFile << endl;
} }
else if(_numFiles == 1) else if(_numFiles == 1)
{ {
@ -97,7 +100,8 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
// has direct access to the actual filesystem (aka, a 'System' node) // has direct access to the actual filesystem (aka, a 'System' node)
// Behind the scenes, this node is actually a platform-specific object // Behind the scenes, this node is actually a platform-specific object
// for whatever system we are running on // for whatever system we are running on
_realNode = FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::Type::SYSTEM); _realNode = FilesystemNodeFactory::create(_zipFile,
FilesystemNodeFactory::Type::SYSTEM);
setFlags(_zipFile, _virtualPath, _realNode); setFlags(_zipFile, _virtualPath, _realNode);
} }
@ -144,11 +148,18 @@ bool FilesystemNodeZIP::exists() const
if(_realNode && _realNode->exists()) if(_realNode && _realNode->exists())
{ {
// We need to inspect the actual path, not just the ZIP file itself // We need to inspect the actual path, not just the ZIP file itself
try
{
myZipHandler->open(_zipFile); myZipHandler->open(_zipFile);
while(myZipHandler->hasNext()) while(myZipHandler->hasNext())
if(BSPF::startsWithIgnoreCase(myZipHandler->next(), _virtualPath)) if(BSPF::startsWithIgnoreCase(myZipHandler->next(), _virtualPath))
return true; return true;
} }
catch(const runtime_error&)
{
// TODO: Actually present the error passed in back to the user
}
}
return false; return false;
} }

View File

@ -63,10 +63,17 @@ void ZipHandler::open(const string& filename)
myZip = std::move(ptr); myZip = std::move(ptr);
// Count ROM files (we do it here so it will be cached) // Count ROM files (we do it here so it will be cached)
try
{
while(hasNext()) while(hasNext())
if(Bankswitch::isValidRomName(next())) if(Bankswitch::isValidRomName(next()))
myZip->myRomfiles++; myZip->myRomfiles++;
} }
catch(...)
{
myZip->myRomfiles = 0;
}
}
reset(); // Reset iterator to beginning for subsequent use reset(); // Reset iterator to beginning for subsequent use
} }
@ -91,7 +98,9 @@ const string& ZipHandler::next()
if(hasNext()) if(hasNext())
{ {
const ZipHeader* header = myZip->nextFile(); const ZipHeader* header = myZip->nextFile();
if(!header || header->uncompressedLength == 0) if(!header)
throw runtime_error(errorMessage(ZipError::FILE_CORRUPT));
else if(header->uncompressedLength == 0)
return next(); return next();
else else
return header->filename; return header->filename;