mirror of
https://github.com/pocoproject/poco.git
synced 2025-11-07 22:40:53 +01:00
fixed GH #2661: Poco::Zip::ZipArchive cannot load new tomcat.zip file
This commit is contained in:
@@ -152,6 +152,7 @@ To decompress single files you must first parse a Zip file, and then decompress
|
|||||||
ZipArchive arch(inp);
|
ZipArchive arch(inp);
|
||||||
ZipArchive::FileHeaders::const_iterator it = arch.findHeader("data/hello.txt");
|
ZipArchive::FileHeaders::const_iterator it = arch.findHeader("data/hello.txt");
|
||||||
poco_assert (it != arch.headerEnd());
|
poco_assert (it != arch.headerEnd());
|
||||||
|
inp.clear();
|
||||||
ZipInputStream zipin(inp, it->second);
|
ZipInputStream zipin(inp, it->second);
|
||||||
std::ostringstream out(std::ios::binary);
|
std::ostringstream out(std::ios::binary);
|
||||||
Poco::StreamCopier::copyStream(zipin, out);
|
Poco::StreamCopier::copyStream(zipin, out);
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ public:
|
|||||||
static void sync(std::istream& in);
|
static void sync(std::istream& in);
|
||||||
/// Searches the next valid header in the input stream, stops right before it
|
/// Searches the next valid header in the input stream, stops right before it
|
||||||
|
|
||||||
|
static void syncDataDescriptor(std::istream& in, bool force64);
|
||||||
|
/// Searches the next data descriptor
|
||||||
|
|
||||||
static void verifyZipEntryFileName(const std::string& zipPath);
|
static void verifyZipEntryFileName(const std::string& zipPath);
|
||||||
/// Verifies that the name of the ZipEntry is a valid path
|
/// Verifies that the name of the ZipEntry is a valid path
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ bool SkipCallback::handleZipEntry(std::istream& zipStream, const ZipLocalFileHea
|
|||||||
if (!hdr.searchCRCAndSizesAfterData())
|
if (!hdr.searchCRCAndSizesAfterData())
|
||||||
zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
|
zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
|
||||||
else
|
else
|
||||||
ZipUtil::sync(zipStream);
|
ZipUtil::syncDataDescriptor(zipStream, hdr.needsZip64());
|
||||||
if (!zipStream.good()) throw Poco::IOException("Failed to seek on input stream");
|
if (!zipStream.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,8 +126,7 @@ void ZipFileInfo::parse(std::istream& inp, bool assumeHeaderRead)
|
|||||||
ptr += 2;
|
ptr += 2;
|
||||||
if (id == ZipCommon::ZIP64_EXTRA_ID)
|
if (id == ZipCommon::ZIP64_EXTRA_ID)
|
||||||
{
|
{
|
||||||
poco_assert(size >= 8);
|
if (size >= 8 && getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
|
||||||
if (getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
|
|
||||||
{
|
{
|
||||||
setUncompressedSize(ZipUtil::get64BitValue(ptr, 0));
|
setUncompressedSize(ZipUtil::get64BitValue(ptr, 0));
|
||||||
size -= 8;
|
size -= 8;
|
||||||
|
|||||||
@@ -161,6 +161,70 @@ void ZipUtil::sync(std::istream& in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ZipUtil::syncDataDescriptor(std::istream & in, bool force64)
|
||||||
|
{
|
||||||
|
std::streampos start = in.tellg();
|
||||||
|
const int eof = std::char_traits<char>::eof();
|
||||||
|
|
||||||
|
int c = in.get();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (c != eof && c != ZipDataInfo::HEADER[0]) { c = in.get(); }
|
||||||
|
|
||||||
|
if (c == eof) return;
|
||||||
|
|
||||||
|
bool match = true;
|
||||||
|
for (int i = 1; i < 4 && match; i++)
|
||||||
|
{
|
||||||
|
c = in.get();
|
||||||
|
if (c != ZipDataInfo::HEADER[i]) match = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
std::streampos end = in.tellg();
|
||||||
|
|
||||||
|
if (force64)
|
||||||
|
{
|
||||||
|
ZipDataInfo64 nfo(in, true);
|
||||||
|
if (nfo.isValid())
|
||||||
|
{
|
||||||
|
if (end - start == nfo.getCompressedSize() + 4)
|
||||||
|
{
|
||||||
|
in.seekg(-static_cast<int>(ZipDataInfo64::getFullHeaderSize()), std::ios::cur);
|
||||||
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in.seekg(-static_cast<int>(ZipDataInfo64::getFullHeaderSize()) + 4, std::ios::cur);
|
||||||
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ZipDataInfo nfo(in, true);
|
||||||
|
if (nfo.isValid())
|
||||||
|
{
|
||||||
|
if (end - start == nfo.getCompressedSize() + 4)
|
||||||
|
{
|
||||||
|
in.seekg(-static_cast<int>(ZipDataInfo::getFullHeaderSize()), std::ios::cur);
|
||||||
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in.seekg(-static_cast<int>(ZipDataInfo::getFullHeaderSize()) + 4, std::ios::cur);
|
||||||
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (c != eof);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ZipUtil::verifyZipEntryFileName(const std::string& fn)
|
void ZipUtil::verifyZipEntryFileName(const std::string& fn)
|
||||||
{
|
{
|
||||||
if (fn.find("\\") != std::string::npos)
|
if (fn.find("\\") != std::string::npos)
|
||||||
|
|||||||
Reference in New Issue
Block a user