mirror of
https://github.com/pocoproject/poco.git
synced 2025-11-05 12:47:47 +01:00
fix for GH #1416: use seekg() instead of multiple putback() operations, which may not work in all cases. Note that this requires the stream passed to Poco::Zip::Decompress to be seekable.
This commit is contained in:
@@ -69,6 +69,7 @@ int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
|||||||
{
|
{
|
||||||
_pIstr->seekg(_start, std::ios_base::beg);
|
_pIstr->seekg(_start, std::ios_base::beg);
|
||||||
_reposition = false;
|
_reposition = false;
|
||||||
|
if (!_pIstr->good()) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_prefix.empty())
|
if (!_prefix.empty())
|
||||||
@@ -145,11 +146,9 @@ int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
|||||||
{
|
{
|
||||||
if (c-1 == byte3)
|
if (c-1 == byte3)
|
||||||
{
|
{
|
||||||
// a match, pushback
|
// a match, seek back first, try pushback as fallback
|
||||||
_pIstr->putback(c);
|
_pIstr->seekg(-4, std::ios::cur);
|
||||||
_pIstr->putback(byte3);
|
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
_pIstr->putback(ZipLocalFileHeader::HEADER[1]);
|
|
||||||
_pIstr->putback(ZipLocalFileHeader::HEADER[0]);
|
|
||||||
_eofDetected = true;
|
_eofDetected = true;
|
||||||
return tempPos;
|
return tempPos;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
|
|||||||
std::string fn = ZipUtil::validZipEntryFileName(fileName);
|
std::string fn = ZipUtil::validZipEntryFileName(fileName);
|
||||||
//bypass the header of the input stream and point to the first byte of the data payload
|
//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);
|
in.seekg(h.getDataStartPos(), std::ios_base::beg);
|
||||||
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
|
|
||||||
if (_files.size() >= 65535)
|
if (_files.size() >= 65535)
|
||||||
throw ZipException("Maximum number of entries for a ZIP file reached: 65535");
|
throw ZipException("Maximum number of entries for a ZIP file reached: 65535");
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ int PartialStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
|||||||
_pIstr->clear();
|
_pIstr->clear();
|
||||||
_pIstr->seekg(_start, std::ios_base::beg);
|
_pIstr->seekg(_start, std::ios_base::beg);
|
||||||
if (_pIstr->fail())
|
if (_pIstr->fail())
|
||||||
throw Poco::IOException("Failed to reposition in stream");
|
throw Poco::IOException("Failed to seek on input stream");
|
||||||
}
|
}
|
||||||
if (!_prefix.empty())
|
if (!_prefix.empty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "Poco/Zip/SkipCallback.h"
|
#include "Poco/Zip/SkipCallback.h"
|
||||||
#include "Poco/Zip/ZipLocalFileHeader.h"
|
#include "Poco/Zip/ZipLocalFileHeader.h"
|
||||||
#include "Poco/Zip/ZipUtil.h"
|
#include "Poco/Zip/ZipUtil.h"
|
||||||
|
#include "Poco/Exception.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@@ -39,6 +40,7 @@ bool SkipCallback::handleZipEntry(std::istream& zipStream, const ZipLocalFileHea
|
|||||||
zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
|
zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
|
||||||
else
|
else
|
||||||
ZipUtil::sync(zipStream);
|
ZipUtil::sync(zipStream);
|
||||||
|
if (!zipStream.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,8 +175,8 @@ int ZipStreamBuf::readFromDevice(char* buffer, std::streamsize length)
|
|||||||
Poco::Int32 size = static_cast<Poco::Int32>(nfo.getFullHeaderSize());
|
Poco::Int32 size = static_cast<Poco::Int32>(nfo.getFullHeaderSize());
|
||||||
_expectedCrc32 = nfo.getCRC32();
|
_expectedCrc32 = nfo.getCRC32();
|
||||||
const char* rawHeader = nfo.getRawHeader();
|
const char* rawHeader = nfo.getRawHeader();
|
||||||
for (Poco::Int32 i = size-1; i >= 0; --i)
|
_pIstr->seekg(-size, std::ios::cur);
|
||||||
_pIstr->putback(rawHeader[i]);
|
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
if (!crcValid())
|
if (!crcValid())
|
||||||
throw ZipException("CRC failure");
|
throw ZipException("CRC failure");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,31 +117,23 @@ void ZipUtil::sync(std::istream& in)
|
|||||||
{
|
{
|
||||||
if (std::memcmp(ZipLocalFileHeader::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
|
if (std::memcmp(ZipLocalFileHeader::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
|
||||||
{
|
{
|
||||||
in.putback(ZipLocalFileHeader::HEADER[3]);
|
in.seekg(-4, std::ios::cur);
|
||||||
in.putback(ZipLocalFileHeader::HEADER[2]);
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
in.putback(ZipLocalFileHeader::HEADER[1]);
|
|
||||||
in.putback(ZipLocalFileHeader::HEADER[0]);
|
|
||||||
}
|
}
|
||||||
else if (std::memcmp(ZipArchiveInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
|
else if (std::memcmp(ZipArchiveInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
|
||||||
{
|
{
|
||||||
in.putback(ZipArchiveInfo::HEADER[3]);
|
in.seekg(-4, std::ios::cur);
|
||||||
in.putback(ZipArchiveInfo::HEADER[2]);
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
in.putback(ZipArchiveInfo::HEADER[1]);
|
|
||||||
in.putback(ZipArchiveInfo::HEADER[0]);
|
|
||||||
}
|
}
|
||||||
else if (std::memcmp(ZipFileInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
|
else if (std::memcmp(ZipFileInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
|
||||||
{
|
{
|
||||||
in.putback(ZipFileInfo::HEADER[3]);
|
in.seekg(-4, std::ios::cur);
|
||||||
in.putback(ZipFileInfo::HEADER[2]);
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
in.putback(ZipFileInfo::HEADER[1]);
|
|
||||||
in.putback(ZipFileInfo::HEADER[0]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
in.putback(ZipDataInfo::HEADER[3]);
|
in.seekg(-4, std::ios::cur);
|
||||||
in.putback(ZipDataInfo::HEADER[2]);
|
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
|
||||||
in.putback(ZipDataInfo::HEADER[1]);
|
|
||||||
in.putback(ZipDataInfo::HEADER[0]);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -149,6 +141,7 @@ void ZipUtil::sync(std::istream& in)
|
|||||||
{
|
{
|
||||||
// we have read 2 bytes, should only be one: putback the last char
|
// we have read 2 bytes, should only be one: putback the last char
|
||||||
in.putback(temp[tempPos - 1]);
|
in.putback(temp[tempPos - 1]);
|
||||||
|
if (!in.good()) throw Poco::IOException("Failed to putback on input stream");
|
||||||
--tempPos;
|
--tempPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user