integrated fixes for #1416 from poco-1.7.6 branch

This commit is contained in:
Guenter Obiltschnig 2016-09-29 20:10:10 +02:00
parent a73eef0487
commit f86dfa8239
13 changed files with 69 additions and 49 deletions

View File

@ -24,7 +24,6 @@
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipFileInfo.h"
#include "Poco/Zip/ZipArchiveInfo.h"
#include <istream>
#include <map>

View File

@ -69,6 +69,7 @@ int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
_pIstr->seekg(_start, std::ios_base::beg);
_reposition = false;
if (!_pIstr->good()) return -1;
}
if (!_prefix.empty())
@ -145,11 +146,9 @@ int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
if (c-1 == byte3)
{
// a match, pushback
_pIstr->putback(c);
_pIstr->putback(byte3);
_pIstr->putback(ZipLocalFileHeader::HEADER[1]);
_pIstr->putback(ZipLocalFileHeader::HEADER[0]);
// a match, seek back
_pIstr->seekg(-4, std::ios::cur);
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
_eofDetected = true;
return tempPos;
}

View File

@ -78,7 +78,7 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt,
_offset = hdr.getEndPos();
_offset += extraDataSize;
_files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr));
poco_assert (_out);
if (!_out) throw Poco::IOException("Bad output stream");
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
@ -89,12 +89,13 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt,
void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const Poco::Path& fileName)
{
if (!in.good())
throw ZipException("Invalid input stream");
std::string fn = ZipUtil::validZipEntryFileName(fileName);
//bypass the header of the input stream and point to the first byte of the data payload
in.seekg(h.getDataStartPos(), std::ios_base::beg);
if (!in.good())
throw ZipException("Invalid input stream");
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
std::streamoff localHeaderOffset = _offset;
ZipLocalFileHeader hdr(h);
@ -161,7 +162,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
}
_files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr));
poco_assert (_out);
if (!_out) throw Poco::IOException("Bad output stream");
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
@ -229,7 +230,7 @@ void Compress::addDirectory(const Poco::Path& entryName, const Poco::DateTime& l
if (hdr.searchCRCAndSizesAfterData())
_offset += extraDataSize;
_files.insert(std::make_pair(entryName.toString(Poco::Path::PATH_UNIX), hdr));
poco_assert (_out);
if (!_out) throw Poco::IOException("Bad output stream");
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
@ -314,7 +315,7 @@ ZipArchive Compress::close()
centralDirSize64 += entrySize;
_offset += entrySize;
}
poco_assert (_out);
if (!_out) throw Poco::IOException("Bad output stream");
Poco::UInt64 numEntries64 = _infos.size();
needZip64 = needZip64 || _offset >= ZipCommon::ZIP64_MAGIC;

View File

@ -39,7 +39,7 @@ Decompress::Decompress(std::istream& in, const Poco::Path& outputDir, bool flatt
{
_outDir.makeAbsolute();
_outDir.makeDirectory();
poco_assert (_in.good());
if (!_in.good()) throw Poco::IOException("Bad input stream");
Poco::File tmp(_outDir);
if (!tmp.exists())
{

View File

@ -69,7 +69,7 @@ int PartialStreamBuf::readFromDevice(char* buffer, std::streamsize length)
_pIstr->clear();
_pIstr->seekg(_start, std::ios_base::beg);
if (_pIstr->fail())
throw Poco::IOException("Failed to reposition in stream");
throw Poco::IOException("Failed to seek on input stream");
}
if (!_prefix.empty())
{

View File

@ -17,6 +17,7 @@
#include "Poco/Zip/SkipCallback.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipUtil.h"
#include "Poco/Exception.h"
namespace Poco {
@ -39,6 +40,7 @@ bool SkipCallback::handleZipEntry(std::istream& zipStream, const ZipLocalFileHea
zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
else
ZipUtil::sync(zipStream);
if (!zipStream.good()) throw Poco::IOException("Failed to seek on input stream");
return true;
}

View File

@ -59,12 +59,16 @@ void ZipArchiveInfo::parse(std::istream& inp, bool assumeHeaderRead)
if (!assumeHeaderRead)
{
inp.read(_rawInfo, ZipCommon::HEADER_SIZE);
if (inp.gcount() != ZipCommon::HEADER_SIZE)
throw Poco::IOException("Failed to read archive info header");
if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad archive info header");
}
else
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
// read the rest of the header
inp.read(_rawInfo + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
Poco::UInt16 len = getZipCommentSize();
@ -136,12 +140,16 @@ void ZipArchiveInfo64::parse(std::istream& inp, bool assumeHeaderRead)
if (!assumeHeaderRead)
{
inp.read(_rawInfo, ZipCommon::HEADER_SIZE);
if (inp.gcount() != ZipCommon::HEADER_SIZE)
throw Poco::IOException("Failed to read archive info header");
if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad archive info header");
}
else
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
std::memset(_rawInfo + ZipCommon::HEADER_SIZE, 0, FULL_HEADER_SIZE - ZipCommon::HEADER_SIZE);
// read the rest of the header
@ -164,7 +172,11 @@ void ZipArchiveInfo64::parse(std::istream& inp, bool assumeHeaderRead)
ZipUtil::set64BitValue(FULL_HEADER_SIZE + len - offset, _rawInfo, RECORDSIZE_POS);
}
inp.read(_locInfo, FULL_LOCATOR_SIZE);
poco_assert (std::memcmp(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE) == 0);
if (inp.gcount() != FULL_LOCATOR_SIZE)
throw Poco::IOException("Failed to read locator");
if (std::memcmp(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad locator header");
}

View File

@ -15,6 +15,7 @@
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Exception.h"
#include <istream>
#include <cstring>
@ -47,10 +48,11 @@ ZipDataInfo::ZipDataInfo(std::istream& in, bool assumeHeaderRead):
else
{
in.read(_rawInfo, ZipCommon::HEADER_SIZE);
if ((!in) || (in.gcount() != ZipCommon::HEADER_SIZE))
return;
if (in.gcount() != ZipCommon::HEADER_SIZE)
throw Poco::IOException("Failed to read data info header");
if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad data info header");
}
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
// now copy the rest of the header
in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = (!in.eof() && in.good());
@ -87,10 +89,12 @@ ZipDataInfo64::ZipDataInfo64(std::istream& in, bool assumeHeaderRead):
else
{
in.read(_rawInfo, ZipCommon::HEADER_SIZE);
if ((!in) || (in.gcount() != ZipCommon::HEADER_SIZE))
return;
if (in.gcount() != ZipCommon::HEADER_SIZE)
throw Poco::IOException("Failed to read data info header");
if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad data info header");
}
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
// now copy the rest of the header
in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = (!in.eof() && in.good());

View File

@ -87,12 +87,16 @@ void ZipFileInfo::parse(std::istream& inp, bool assumeHeaderRead)
if (!assumeHeaderRead)
{
inp.read(_rawInfo, ZipCommon::HEADER_SIZE);
if (inp.gcount() != ZipCommon::HEADER_SIZE)
throw Poco::IOException("Failed to read file info header");
if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad file info header");
}
else
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
// read the rest of the header
inp.read(_rawInfo + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_crc32 = getCRCFromHeader();

View File

@ -118,13 +118,17 @@ void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead)
if (!assumeHeaderRead)
{
inp.read(_rawHeader, ZipCommon::HEADER_SIZE);
if (inp.gcount() != ZipCommon::HEADER_SIZE)
throw Poco::IOException("Failed to read local file header");
if (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) != 0)
throw Poco::DataFormatException("Bad local file header");
}
else
{
std::memcpy(_rawHeader, HEADER, ZipCommon::HEADER_SIZE);
}
poco_assert (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) == 0);
// read the rest of the header
// read the rest of the header
inp.read(_rawHeader + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
poco_assert (_rawHeader[VERSION_POS + 1]>= ZipCommon::HS_FAT && _rawHeader[VERSION_POS + 1] < ZipCommon::HS_UNUSED);
poco_assert (getMajorVersionNumber() <= 4); // Allow for Zip64 version 4.5

View File

@ -111,7 +111,7 @@ const ZipLocalFileHeader& ZipManipulator::getForChange(const std::string& zipPat
{
ZipArchive::FileHeaders::const_iterator it = _in->findHeader(zipPath);
if (it == _in->headerEnd())
throw ZipManipulationException("entry not found: " + zipPath);
throw ZipManipulationException("Entry not found: " + zipPath);
if (_changes.find(zipPath) != _changes.end())
throw ZipManipulationException("A change request exists already for entry " + zipPath);

View File

@ -177,8 +177,8 @@ int ZipStreamBuf::readFromDevice(char* buffer, std::streamsize length)
Poco::Int32 size = static_cast<Poco::Int32>(nfo.getFullHeaderSize());
_expectedCrc32 = nfo.getCRC32();
const char* rawHeader = nfo.getRawHeader();
for (Poco::Int32 i = size-1; i >= 0; --i)
_pIstr->putback(rawHeader[i]);
_pIstr->seekg(-size, std::ios::cur);
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
if (!crcValid())
throw ZipException("CRC failure");
}
@ -215,7 +215,8 @@ void ZipStreamBuf::close(Poco::UInt64& extraDataSize)
_ptrOHelper->close();
}
_ptrOBuf = 0;
poco_assert (*_pOstr);
if (!*_pOstr) throw Poco::IOException("Bad output stream");
// write an extra datablock if required
// or fix the crc entries
poco_check_ptr(_pHeader);
@ -248,13 +249,14 @@ void ZipStreamBuf::close(Poco::UInt64& extraDataSize)
else
{
_pOstr->seekp(_pHeader->getStartPos(), std::ios_base::beg);
poco_assert (*_pOstr);
if (!*_pOstr) throw Poco::IOException("Bad output stream");
if (_pHeader->hasExtraField()) // Update sizes in header extension.
_pHeader->setZip64Data();
std::string header = _pHeader->createHeader();
_pOstr->write(header.c_str(), static_cast<std::streamsize>(header.size()));
_pOstr->seekp(0, std::ios_base::end);
poco_assert (*_pOstr);
if (!*_pOstr) throw Poco::IOException("Bad output stream");
}
_pHeader = 0;
}

View File

@ -117,31 +117,23 @@ void ZipUtil::sync(std::istream& in)
{
if (std::memcmp(ZipLocalFileHeader::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
{
in.putback(ZipLocalFileHeader::HEADER[3]);
in.putback(ZipLocalFileHeader::HEADER[2]);
in.putback(ZipLocalFileHeader::HEADER[1]);
in.putback(ZipLocalFileHeader::HEADER[0]);
in.seekg(-4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
else if (std::memcmp(ZipArchiveInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
{
in.putback(ZipArchiveInfo::HEADER[3]);
in.putback(ZipArchiveInfo::HEADER[2]);
in.putback(ZipArchiveInfo::HEADER[1]);
in.putback(ZipArchiveInfo::HEADER[0]);
in.seekg(-4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
else if (std::memcmp(ZipFileInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
{
in.putback(ZipFileInfo::HEADER[3]);
in.putback(ZipFileInfo::HEADER[2]);
in.putback(ZipFileInfo::HEADER[1]);
in.putback(ZipFileInfo::HEADER[0]);
in.seekg(-4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
else
{
in.putback(ZipDataInfo::HEADER[3]);
in.putback(ZipDataInfo::HEADER[2]);
in.putback(ZipDataInfo::HEADER[1]);
in.putback(ZipDataInfo::HEADER[0]);
in.seekg(-4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
return;
}
@ -149,6 +141,7 @@ void ZipUtil::sync(std::istream& in)
{
// we have read 2 bytes, should only be one: putback the last char
in.putback(temp[tempPos - 1]);
if (!in.good()) throw Poco::IOException("Failed to putback on input stream");
--tempPos;
}
}