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:32:01 +01:00
parent 7c81a551c4
commit 4ddce11dc0
4 changed files with 11 additions and 2 deletions

View File

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

View File

@ -114,7 +114,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
{ {
Poco::Buffer<char> buffer(COMPRESS_CHUNK_SIZE); Poco::Buffer<char> buffer(COMPRESS_CHUNK_SIZE);
Poco::UInt32 remaining = totalSize; Poco::UInt32 remaining = totalSize;
while(remaining > 0) while (remaining > 0)
{ {
if (remaining > COMPRESS_CHUNK_SIZE) if (remaining > COMPRESS_CHUNK_SIZE)
{ {

View File

@ -219,6 +219,13 @@ void ZipStreamBuf::close()
_pHeader->setCRC(_crc32.checksum()); _pHeader->setCRC(_crc32.checksum());
_pHeader->setUncompressedSize(_bytesWritten); _pHeader->setUncompressedSize(_bytesWritten);
_pHeader->setCompressedSize(_ptrOHelper->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 _pHeader->setStartPos(_pHeader->getStartPos()); // This resets EndPos now that compressed Size is known
if (_pHeader->searchCRCAndSizesAfterData()) if (_pHeader->searchCRCAndSizesAfterData())

View File

@ -106,7 +106,7 @@ void ZipUtil::sync(std::istream& in)
while (in.good() && !in.eof()) while (in.good() && !in.eof())
{ {
// all zip headers start withe same 2byte prefix // 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! // we have a possible header!
// read the next 2 bytes // read the next 2 bytes