one more fix for #1597: check for empty streams in Compress::addEntry() so this also works with non-seekable output streams

This commit is contained in:
Guenter Obiltschnig 2017-02-17 20:18:57 +01:00
parent dc84b22c99
commit 86333d9103

View File

@ -57,9 +57,14 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt,
{
std::string ext = Poco::toLower(fileName.getExtension());
if (_storeExtensions.find(ext) != _storeExtensions.end())
{
cm = ZipCommon::CM_STORE;
cl = ZipCommon::CL_NORMAL;
}
else
{
cm = ZipCommon::CM_DEFLATE;
}
}
std::string fn = ZipUtil::validZipEntryFileName(fileName);
@ -67,12 +72,27 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt,
if (!in.good())
throw ZipException("Invalid input stream");
// Check if stream is empty.
// In this case, we have to set compression to STORE, otherwise
// extraction will fail with various tools.
const int eof = std::char_traits<char>::eof();
int firstChar = in.get();
if (firstChar == eof)
{
cm = ZipCommon::CM_STORE;
cl = ZipCommon::CL_NORMAL;
}
std::streamoff localHeaderOffset = _offset;
ZipLocalFileHeader hdr(fileName, lastModifiedAt, cm, cl, _forceZip64);
hdr.setStartPos(localHeaderOffset);
ZipOutputStream zipOut(_out, hdr, _seekableOut);
Poco::StreamCopier::copyStream(in, zipOut);
if (firstChar != eof)
{
zipOut.put(static_cast<char>(firstChar));
Poco::StreamCopier::copyStream(in, zipOut);
}
Poco::UInt64 extraDataSize;
zipOut.close(extraDataSize);
_offset = hdr.getEndPos();