fixed GH #1597: adding empty file to zip leads to archive that can't be unzipped by windows

This commit is contained in:
Guenter Obiltschnig 2017-02-17 15:39:36 +01:00
parent 17f8102090
commit 158db947cb
4 changed files with 14 additions and 5 deletions

View File

@ -205,6 +205,8 @@ private:
Poco::UInt32 _crc32;
Poco::UInt64 _compressedSize;
Poco::UInt64 _uncompressedSize;
friend class ZipStreamBuf;
};

View File

@ -101,7 +101,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
ZipLocalFileHeader hdr(h);
hdr.setFileName(fn, h.isDirectory());
hdr.setStartPos(localHeaderOffset);
if(hdr.needsZip64())
if (hdr.needsZip64())
hdr.setZip64Data();
//bypass zipoutputstream
//write the header directly
@ -113,7 +113,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
{
Poco::Buffer<char> buffer(COMPRESS_CHUNK_SIZE);
Poco::UInt64 remaining = totalSize;
while(remaining > 0)
while (remaining > 0)
{
if (remaining > COMPRESS_CHUNK_SIZE)
{
@ -153,7 +153,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
}
else
{
if(hdr.hasExtraField()) // Update sizes in header extension.
if (hdr.hasExtraField()) // Update sizes in header extension.
hdr.setZip64Data();
_out.seekp(hdr.getStartPos(), std::ios_base::beg);
std::string header = hdr.createHeader();
@ -319,7 +319,7 @@ ZipArchive Compress::close()
Poco::UInt64 numEntries64 = _infos.size();
needZip64 = needZip64 || _offset >= ZipCommon::ZIP64_MAGIC;
if(needZip64)
if (needZip64)
{
ZipArchiveInfo64 central;
central.setCentralDirectorySize(centralDirSize64);

View File

@ -223,6 +223,13 @@ void ZipStreamBuf::close(Poco::UInt64& extraDataSize)
_pHeader->setCRC(_crc32.checksum());
_pHeader->setUncompressedSize(_bytesWritten);
_pHeader->setCompressedSize(_ptrOHelper->bytesWritten());
if (_bytesWritten == 0)
{
poco_assert (_ptrOHelper->bytesWritten() == 0);
// Empty files must use CM_STORE, otherwise unzipping will fail
_pHeader->setCompressionMethod(ZipCommon::CM_STORE);
_pHeader->setCompressionLevel(ZipCommon::CL_NORMAL);
}
_pHeader->setStartPos(_pHeader->getStartPos()); // This resets EndPos now that compressed Size is known
if (_pHeader->searchCRCAndSizesAfterData())

View File

@ -106,7 +106,7 @@ void ZipUtil::sync(std::istream& in)
while (in.good() && !in.eof())
{
// all zip headers start withe same 2byte prefix
if(std::memcmp(ZipLocalFileHeader::HEADER, &temp[tempPos - PREFIX], PREFIX) == 0)
if (std::memcmp(ZipLocalFileHeader::HEADER, &temp[tempPos - PREFIX], PREFIX) == 0)
{
// we have a possible header!
// read the next 2 bytes