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

View File

@ -63,9 +63,16 @@ void ZipHandler::open(const string& filename)
myZip = std::move(ptr);
// Count ROM files (we do it here so it will be cached)
while(hasNext())
if(Bankswitch::isValidRomName(next()))
myZip->myRomfiles++;
try
{
while(hasNext())
if(Bankswitch::isValidRomName(next()))
myZip->myRomfiles++;
}
catch(...)
{
myZip->myRomfiles = 0;
}
}
reset(); // Reset iterator to beginning for subsequent use
@ -91,7 +98,9 @@ const string& ZipHandler::next()
if(hasNext())
{
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();
else
return header->filename;