Packages: fix handling of unsafe paths in zips

This was breaking the P-51D which contains a mis-named PNG file which
tripped the unsafe path detection.
This commit is contained in:
James Turner 2020-03-24 13:51:39 +00:00
parent 73f00bd842
commit 8cf11f9208
3 changed files with 30 additions and 23 deletions

View File

@ -340,7 +340,7 @@ public:
} }
if (!isSafePath(tarPath)) { if (!isSafePath(tarPath)) {
SG_LOG(SG_IO, SG_WARN, "bad tar path:" << tarPath); SG_LOG(SG_IO, SG_WARN, "unsafe tar path, skipping::" << tarPath);
skipCurrentEntry = true; skipCurrentEntry = true;
} }
@ -506,7 +506,7 @@ public:
#endif #endif
unzFile zip = unzOpen2(bufferName, &memoryAccessFuncs); unzFile zip = unzOpen2(bufferName, &memoryAccessFuncs);
const size_t BUFFER_SIZE = 32 * 1024; const size_t BUFFER_SIZE = 1024 * 1024;
void* buf = malloc(BUFFER_SIZE); void* buf = malloc(BUFFER_SIZE);
try { try {
@ -532,24 +532,28 @@ public:
state = END_OF_ARCHIVE; state = END_OF_ARCHIVE;
} }
catch (sg_exception&) { catch (sg_exception&) {
state = BAD_ARCHIVE; state = BAD_ARCHIVE;
} }
free(buf); free(buf);
unzClose(zip); unzClose(zip);
} }
void extractCurrentFile(unzFile zip, char* buffer, size_t bufferSize) void extractCurrentFile(unzFile zip, char* buffer, size_t bufferSize)
{ {
unz_file_info fileInfo; unz_file_info fileInfo;
unzGetCurrentFileInfo(zip, &fileInfo, int result = unzGetCurrentFileInfo(zip, &fileInfo,
buffer, bufferSize, buffer, bufferSize,
NULL, 0, /* extra field */ NULL, 0, /* extra field */
NULL, 0 /* comment field */); NULL, 0 /* comment field */);
if (result != Z_OK) {
throw sg_io_exception("Failed to get zip current file info");
}
std::string name(buffer); std::string name(buffer);
if (!isSafePath(name)) { if (!isSafePath(name)) {
throw sg_format_exception("Bad zip path", name); SG_LOG(SG_IO, SG_WARN, "unsafe zip path, skipping::" << name);
return;
} }
auto filterResult = filterPath(name); auto filterResult = filterPath(name);
@ -568,7 +572,7 @@ public:
return; return;
} }
int result = unzOpenCurrentFile(zip); result = unzOpenCurrentFile(zip);
if (result != UNZ_OK) { if (result != UNZ_OK) {
throw sg_io_exception("opening current zip file failed", sg_location(name)); throw sg_io_exception("opening current zip file failed", sg_location(name));
} }

View File

@ -122,6 +122,9 @@ protected:
m_downloaded += n; m_downloaded += n;
m_owner->installProgress(m_downloaded, responseLength()); m_owner->installProgress(m_downloaded, responseLength());
m_extractor->extractBytes(ubytes, n); m_extractor->extractBytes(ubytes, n);
if (m_extractor->hasError()) {
SG_LOG(SG_GENERAL, SG_WARN, "archive extraction failed");
}
} }
void onDone() override void onDone() override

View File

@ -59,7 +59,7 @@ public:
virtual void installProgress(pkg::InstallRef aInstall, unsigned int bytes, unsigned int total) virtual void installProgress(pkg::InstallRef aInstall, unsigned int bytes, unsigned int total)
{ {
unsigned int percent = (bytes * 100) / total; size_t percent = (static_cast<size_t>(bytes) * 100) / total;
if (percent == _lastPercent) { if (percent == _lastPercent) {
return; return;
} }
@ -78,7 +78,7 @@ public:
} }
private: private:
unsigned int _lastPercent; size_t _lastPercent;
}; };
@ -124,8 +124,8 @@ int main(int argc, char** argv)
{ {
HTTP::Client* http = new HTTP::Client(); HTTP::Client* http = new HTTP::Client();
pkg::Root* root = new pkg::Root(Dir::current().path(), ""); pkg::Root* root = new pkg::Root(Dir::current().path(), "2019.1.1");
MyDelegate dlg; MyDelegate dlg;
root->addDelegate(&dlg); root->addDelegate(&dlg);