1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-09-13 18:47:10 +02:00

Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions

38
vendor/POCO/Zip/src/Add.cpp vendored Normal file
View File

@@ -0,0 +1,38 @@
//
// Add.cpp
//
// Library: Zip
// Package: Manipulation
// Module: Add
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Add.h"
#include "Poco/Zip/Compress.h"
namespace Poco {
namespace Zip {
Add::Add(const std::string& zipPath, const std::string& localPath, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl):
_zipPath(zipPath),
_localPath(localPath),
_cm(cm),
_cl(cl)
{
}
void Add::execute(Compress& c, std::istream& input)
{
c.addFile(Poco::Path(_localPath), Poco::Path(_zipPath), _cm, _cl);
}
} } // namespace Poco::Zip

229
vendor/POCO/Zip/src/AutoDetectStream.cpp vendored Normal file
View File

@@ -0,0 +1,229 @@
//
// AutoDetectStream.cpp
//
// Library: Zip
// Package: Zip
// Module: AutoDetectStream
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/AutoDetectStream.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipArchiveInfo.h"
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Zip/ZipFileInfo.h"
#include "Poco/Exception.h"
#include <cstring>
namespace Poco {
namespace Zip {
AutoDetectStreamBuf::AutoDetectStreamBuf(std::istream& in, const std::string& pre, const std::string& post, bool reposition, Poco::UInt32 start, bool needsZip64):
Poco::BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
_pIstr(&in),
_eofDetected(false),
_matchCnt(0),
_prefix(pre),
_postfix(post),
_reposition(reposition),
_start(start),
_needsZip64(needsZip64),
_length(0)
{
}
AutoDetectStreamBuf::~AutoDetectStreamBuf()
{
}
int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
poco_assert_dbg(length >= 8);
if (_pIstr == 0 || length == 0) return -1;
if (_reposition)
{
_pIstr->seekg(_start, std::ios_base::beg);
_reposition = false;
if (!_pIstr->good()) return -1;
}
if (!_prefix.empty())
{
std::streamsize n = (_prefix.size() > length) ? length : static_cast<std::streamsize>(_prefix.size());
std::memcpy(buffer, _prefix.data(), n);
_prefix.erase(0, n);
return static_cast<int>(n);
}
if (_eofDetected)
{
if (!_postfix.empty())
{
std::streamsize n = (_postfix.size() > length) ? length : static_cast<std::streamsize>(_postfix.size());
std::memcpy(buffer, _postfix.data(), n);
_postfix.erase(0, n);
return static_cast<int>(n);
}
else return -1;
}
if (!_pIstr->good()) return -1;
std::streamsize offset = 0;
static std::istream::int_type eof = std::istream::traits_type::eof();
while (_pIstr->good() && !_pIstr->eof() && (offset + 4) < length)
{
std::istream::int_type c = _pIstr->get();
if (c != eof)
{
if (_matchCnt < 3)
{
if (c == ZipDataInfo::HEADER[_matchCnt])
{
++_matchCnt;
}
else
{
for (int i = 0; i < _matchCnt; i++)
{
buffer[offset++] = ZipDataInfo::HEADER[i];
}
if (c == ZipDataInfo::HEADER[0])
{
_matchCnt = 1;
}
else
{
_matchCnt = 0;
buffer[offset++] = static_cast<char>(c);
}
}
}
else if (_matchCnt == 3)
{
if (ZipDataInfo::HEADER[3] == c)
{
std::streamsize dataInfoSize = 0;
if (_needsZip64)
{
ZipDataInfo64 dataInfo(*_pIstr, true);
if (!_pIstr->good()) throw Poco::IOException("Failed to read data descriptor");
dataInfoSize = dataInfo.getFullHeaderSize();
if (dataInfo.getCompressedSize() == _length + offset)
{
_pIstr->seekg(-static_cast<int>(dataInfoSize), std::ios::cur);
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
_eofDetected = true;
_length += offset;
if (offset == 0 && !_postfix.empty())
{
offset = (_postfix.size() > length) ? length : static_cast<std::streamsize>(_postfix.size());
std::memcpy(buffer, _postfix.data(), offset);
_postfix.erase(0, offset);
}
return static_cast<int>(offset);
}
}
else
{
ZipDataInfo dataInfo(*_pIstr, true);
if (!_pIstr->good()) throw Poco::IOException("Failed to read data descriptor");
dataInfoSize = dataInfo.getFullHeaderSize();
if (dataInfo.getCompressedSize() == _length + offset)
{
_pIstr->seekg(-static_cast<int>(dataInfoSize), std::ios::cur);
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
_eofDetected = true;
_length += offset;
if (offset == 0 && !_postfix.empty())
{
offset = (_postfix.size() > length) ? length : static_cast<std::streamsize>(_postfix.size());
std::memcpy(buffer, _postfix.data(), offset);
_postfix.erase(0, offset);
}
return static_cast<int>(offset);
}
}
_pIstr->seekg(-static_cast<int>(dataInfoSize - 4), std::ios::cur);
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
buffer[offset++] = ZipDataInfo::HEADER[0];
buffer[offset++] = ZipDataInfo::HEADER[1];
buffer[offset++] = ZipDataInfo::HEADER[2];
buffer[offset++] = ZipDataInfo::HEADER[3];
_matchCnt = 0;
}
else
{
buffer[offset++] = ZipDataInfo::HEADER[0];
buffer[offset++] = ZipDataInfo::HEADER[1];
buffer[offset++] = ZipDataInfo::HEADER[2];
buffer[offset++] = c;
_matchCnt = 0;
}
}
}
}
_length += offset;
return static_cast<int>(offset);
}
int AutoDetectStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
{
return -1; // not supported
}
AutoDetectIOS::AutoDetectIOS(std::istream& istr, const std::string& pre, const std::string& post, bool reposition, Poco::UInt32 start, bool needsZip64):
_buf(istr, pre, post, reposition, start, needsZip64)
{
poco_ios_init(&_buf);
}
AutoDetectIOS::~AutoDetectIOS()
{
}
AutoDetectStreamBuf* AutoDetectIOS::rdbuf()
{
return &_buf;
}
AutoDetectInputStream::AutoDetectInputStream(std::istream& istr, const std::string& pre, const std::string& post, bool reposition, Poco::UInt32 start, bool needsZip64):
AutoDetectIOS(istr, pre, post, reposition, start, needsZip64),
std::istream(&_buf)
{
}
AutoDetectInputStream::~AutoDetectInputStream()
{
}
} } // namespace Poco::Zip

389
vendor/POCO/Zip/src/Compress.cpp vendored Normal file
View File

@@ -0,0 +1,389 @@
//
// Compress.cpp
//
// Library: Zip
// Package: Zip
// Module: Compress
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Compress.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipStream.h"
#include "Poco/Zip/ZipArchiveInfo.h"
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Zip/ZipException.h"
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/FileStream.h"
#include "Poco/String.h"
namespace Poco {
namespace Zip {
Compress::Compress(std::ostream& out, bool seekableOut, bool forceZip64):
_out(out),
_seekableOut(seekableOut),
_forceZip64(forceZip64),
_files(),
_infos(),
_dirs(),
_offset(0)
{
_storeExtensions.insert("gif");
_storeExtensions.insert("png");
_storeExtensions.insert("jpg");
_storeExtensions.insert("jpeg");
}
Compress::~Compress()
{
}
void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt, const Poco::Path& fileName, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
{
if (cm == ZipCommon::CM_AUTO)
{
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);
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);
if (firstChar != eof)
{
zipOut.put(static_cast<char>(firstChar));
Poco::StreamCopier::copyStream(in, zipOut);
}
Poco::UInt64 extraDataSize;
zipOut.close(extraDataSize);
_offset = hdr.getEndPos();
_offset += extraDataSize;
_files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr));
if (!_out) throw Poco::IOException("Bad output stream");
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
_infos.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), nfo));
EDone.notify(this, hdr);
}
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 Poco::IOException("Failed to seek on input stream");
std::streamoff localHeaderOffset = _offset;
ZipLocalFileHeader hdr(h);
hdr.setFileName(fn, h.isDirectory());
hdr.setStartPos(localHeaderOffset);
if (hdr.needsZip64())
hdr.setZip64Data();
//bypass zipoutputstream
//write the header directly
std::string header = hdr.createHeader();
_out.write(header.c_str(), static_cast<std::streamsize>(header.size()));
// now fwd the payload to _out in chunks of size CHUNKSIZE
Poco::UInt64 totalSize = hdr.getCompressedSize();
if (totalSize > 0)
{
Poco::Buffer<char> buffer(COMPRESS_CHUNK_SIZE);
Poco::UInt64 remaining = totalSize;
while (remaining > 0)
{
if (remaining > COMPRESS_CHUNK_SIZE)
{
in.read(buffer.begin(), COMPRESS_CHUNK_SIZE);
std::streamsize n = in.gcount();
poco_assert_dbg (n == COMPRESS_CHUNK_SIZE);
_out.write(buffer.begin(), n);
remaining -= COMPRESS_CHUNK_SIZE;
}
else
{
in.read(buffer.begin(), remaining);
std::streamsize n = in.gcount();
poco_assert_dbg (n == remaining);
_out.write(buffer.begin(), n);
remaining = 0;
}
}
}
hdr.setStartPos(localHeaderOffset); // This resets EndPos now that compressed Size is known
_offset = hdr.getEndPos();
//write optional block afterwards
if (hdr.searchCRCAndSizesAfterData())
{
if (hdr.needsZip64())
{
ZipDataInfo64 info(in, false);
_out.write(info.getRawHeader(), static_cast<std::streamsize>(info.getFullHeaderSize()));
_offset += ZipDataInfo::getFullHeaderSize();
}
else
{
ZipDataInfo info(in, false);
_out.write(info.getRawHeader(), static_cast<std::streamsize>(info.getFullHeaderSize()));
_offset += ZipDataInfo::getFullHeaderSize();
}
}
else
{
if (hdr.hasExtraField()) // Update sizes in header extension.
hdr.setZip64Data();
_out.seekp(hdr.getStartPos(), std::ios_base::beg);
std::string header = hdr.createHeader();
_out.write(header.c_str(), static_cast<std::streamsize>(header.size()));
_out.seekp(0, std::ios_base::end);
}
_files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr));
if (!_out) throw Poco::IOException("Bad output stream");
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
_infos.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), nfo));
EDone.notify(this, hdr);
}
void Compress::addFile(std::istream& in, const Poco::DateTime& lastModifiedAt, const Poco::Path& fileName, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
{
if (!fileName.isFile())
throw ZipException("Not a file: "+ fileName.toString());
if (fileName.depth() > 1)
{
addDirectory(fileName.parent(), lastModifiedAt);
}
addEntry(in, lastModifiedAt, fileName, cm, cl);
}
void Compress::addFile(const Poco::Path& file, const Poco::Path& fileName, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
{
Poco::File aFile(file);
Poco::FileInputStream in(file.toString());
if (fileName.depth() > 1)
{
Poco::File aParent(file.parent());
addDirectory(fileName.parent(), aParent.getLastModified());
}
addFile(in, aFile.getLastModified(), fileName, cm, cl);
}
void Compress::addDirectory(const Poco::Path& entryName, const Poco::DateTime& lastModifiedAt)
{
if (!entryName.isDirectory())
throw ZipException("Not a directory: "+ entryName.toString());
std::string fileStr = entryName.toString(Poco::Path::PATH_UNIX);
if (_files.find(fileStr) != _files.end())
return; // ignore duplicate add
if (fileStr == "/")
throw ZipException("Illegal entry name /");
if (fileStr.empty())
throw ZipException("Illegal empty entry name");
if (!ZipCommon::isValidPath(fileStr))
throw ZipException("Illegal entry name " + fileStr + " containing parent directory reference");
if (entryName.depth() > 1)
{
addDirectory(entryName.parent(), lastModifiedAt);
}
std::streamoff localHeaderOffset = _offset;
ZipCommon::CompressionMethod cm = ZipCommon::CM_STORE;
ZipCommon::CompressionLevel cl = ZipCommon::CL_NORMAL;
ZipLocalFileHeader hdr(entryName, lastModifiedAt, cm, cl);
hdr.setStartPos(localHeaderOffset);
ZipOutputStream zipOut(_out, hdr, _seekableOut);
Poco::UInt64 extraDataSize;
zipOut.close(extraDataSize);
hdr.setStartPos(localHeaderOffset); // reset again now that compressed Size is known
_offset = hdr.getEndPos();
if (hdr.searchCRCAndSizesAfterData())
_offset += extraDataSize;
_files.insert(std::make_pair(entryName.toString(Poco::Path::PATH_UNIX), hdr));
if (!_out) throw Poco::IOException("Bad output stream");
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
_infos.insert(std::make_pair(entryName.toString(Poco::Path::PATH_UNIX), nfo));
EDone.notify(this, hdr);
}
void Compress::addRecursive(const Poco::Path& entry, ZipCommon::CompressionLevel cl, bool excludeRoot, const Poco::Path& name)
{
addRecursive(entry, ZipCommon::CM_DEFLATE, cl, excludeRoot, name);
}
void Compress::addRecursive(const Poco::Path& entry, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl, bool excludeRoot, const Poco::Path& name)
{
Poco::File aFile(entry);
if (!aFile.isDirectory())
throw ZipException("Not a directory: "+ entry.toString());
Poco::Path aName(name);
aName.makeDirectory();
if (!excludeRoot)
{
if (aName.depth() == 0)
{
Poco::Path tmp(entry);
tmp.makeAbsolute(); // eliminate ../
aName = Poco::Path(tmp[tmp.depth()-1]);
aName.makeDirectory();
}
addDirectory(aName, aFile.getLastModified());
}
// iterate over children
std::vector<std::string> children;
aFile.list(children);
std::vector<std::string>::const_iterator it = children.begin();
std::vector<std::string>::const_iterator itEnd = children.end();
for (; it != itEnd; ++it)
{
Poco::Path realFile(entry, *it);
Poco::Path renamedFile(aName, *it);
Poco::File aFile(realFile);
if (aFile.isDirectory())
{
realFile.makeDirectory();
renamedFile.makeDirectory();
addRecursive(realFile, cm, cl, false, renamedFile);
}
else
{
realFile.makeFile();
renamedFile.makeFile();
addFile(realFile, renamedFile, cm, cl);
}
}
}
ZipArchive Compress::close()
{
if (!_dirs.empty() || ! _dirs64.empty())
return ZipArchive(_files, _infos, _dirs, _dirs64);
poco_assert (_infos.size() == _files.size());
Poco::UInt64 centralDirSize64 = 0;
Poco::UInt64 centralDirStart64 = _offset;
// write all infos
ZipArchive::FileInfos::const_iterator it = _infos.begin();
ZipArchive::FileInfos::const_iterator itEnd = _infos.end();
bool needZip64 = _forceZip64;
needZip64 = needZip64 || _files.size() >= ZipCommon::ZIP64_MAGIC_SHORT || centralDirStart64 >= ZipCommon::ZIP64_MAGIC;
for (; it != itEnd; ++it)
{
const ZipFileInfo& nfo = it->second;
needZip64 = needZip64 || nfo.needsZip64();
std::string info(nfo.createHeader());
_out.write(info.c_str(), static_cast<std::streamsize>(info.size()));
Poco::UInt32 entrySize = static_cast<Poco::UInt32>(info.size());
centralDirSize64 += entrySize;
_offset += entrySize;
}
if (!_out) throw Poco::IOException("Bad output stream");
Poco::UInt64 numEntries64 = _infos.size();
needZip64 = needZip64 || _offset >= ZipCommon::ZIP64_MAGIC;
if (needZip64)
{
ZipArchiveInfo64 central;
central.setCentralDirectorySize(centralDirSize64);
central.setCentralDirectoryOffset(centralDirStart64);
central.setNumberOfEntries(numEntries64);
central.setTotalNumberOfEntries(numEntries64);
central.setHeaderOffset(_offset);
central.setTotalNumberOfDisks(1);
std::string centr(central.createHeader());
_out.write(centr.c_str(), static_cast<std::streamsize>(centr.size()));
_out.flush();
_offset += centr.size();
_dirs64.insert(std::make_pair(0, central));
}
Poco::UInt16 numEntries = numEntries64 >= ZipCommon::ZIP64_MAGIC_SHORT ? ZipCommon::ZIP64_MAGIC_SHORT : static_cast<Poco::UInt16>(numEntries64);
Poco::UInt32 centralDirStart = centralDirStart64 >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(centralDirStart64);
Poco::UInt32 centralDirSize = centralDirSize64 >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(centralDirSize64);
Poco::UInt32 offset = _offset >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(_offset);
ZipArchiveInfo central;
central.setCentralDirectorySize(centralDirSize);
central.setCentralDirectoryOffset(centralDirStart);
central.setNumberOfEntries(numEntries);
central.setTotalNumberOfEntries(numEntries);
central.setHeaderOffset(offset);
if (!_comment.empty() && _comment.size() <= 65535)
{
central.setZipComment(_comment);
}
std::string centr(central.createHeader());
_out.write(centr.c_str(), static_cast<std::streamsize>(centr.size()));
_out.flush();
_offset += centr.size();
_dirs.insert(std::make_pair(0, central));
return ZipArchive(_files, _infos, _dirs, _dirs64);
}
void Compress::setStoreExtensions(const std::set<std::string>& extensions)
{
_storeExtensions.clear();
for (std::set<std::string>::const_iterator it = extensions.begin(); it != extensions.end(); ++it)
{
_storeExtensions.insert(Poco::toLower(*it));
}
}
} } // namespace Poco::Zip

187
vendor/POCO/Zip/src/Decompress.cpp vendored Normal file
View File

@@ -0,0 +1,187 @@
//
// Decompress.cpp
//
// Library: Zip
// Package: Zip
// Module: Decompress
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Decompress.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipArchive.h"
#include "Poco/Zip/ZipStream.h"
#include "Poco/Zip/ZipException.h"
#include "Poco/File.h"
#include "Poco/Exception.h"
#include "Poco/StreamCopier.h"
#include "Poco/Delegate.h"
#include "Poco/FileStream.h"
#include "Poco/Format.h"
namespace Poco {
namespace Zip {
Decompress::Decompress(std::istream& in, const Poco::Path& outputDir, bool flattenDirs, bool keepIncompleteFiles):
_in(in),
_outDir(outputDir),
_flattenDirs(flattenDirs),
_keepIncompleteFiles(keepIncompleteFiles),
_mapping()
{
_outDir.makeAbsolute();
_outDir.makeDirectory();
if (!_in.good()) throw Poco::IOException("Bad input stream");
Poco::File tmp(_outDir);
if (!tmp.exists())
{
tmp.createDirectories();
}
if (!tmp.isDirectory())
throw Poco::IOException("Failed to create/open directory: " + _outDir.toString());
EOk += Poco::Delegate<Decompress, std::pair<const ZipLocalFileHeader, const Poco::Path>>(this, &Decompress::onOk);
}
Decompress::~Decompress()
{
try
{
EOk -= Poco::Delegate<Decompress, std::pair<const ZipLocalFileHeader, const Poco::Path>>(this, &Decompress::onOk);
}
catch (...)
{
poco_unexpected();
}
}
ZipArchive Decompress::decompressAllFiles()
{
poco_assert (_mapping.empty());
ZipArchive arch(_in, *this);
return arch;
}
bool Decompress::handleZipEntry(std::istream& zipStream, const ZipLocalFileHeader& hdr)
{
if (hdr.isDirectory())
{
// directory have 0 size, nth to read
if (!_flattenDirs)
{
std::string dirName = hdr.getFileName();
if (!ZipCommon::isValidPath(dirName))
throw ZipException("Illegal entry name", dirName);
Poco::Path dir(_outDir, dirName);
dir.makeDirectory();
Poco::File aFile(dir);
aFile.createDirectories();
}
if (hdr.getCompressionMethod() == ZipCommon::CM_DEFLATE)
{
// If directory is stored with deflate method, two extra bytes
// (the result of deflating a zero-length sequence) must be read.
char buffer[2];
zipStream.read(buffer, 2);
}
return true;
}
try
{
std::string fileName = hdr.getFileName();
if (_flattenDirs)
{
// remove path info
Poco::Path p(fileName);
p.makeFile();
fileName = p.getFileName();
}
if (!ZipCommon::isValidPath(fileName))
{
throw ZipException("Illegal entry name", fileName);
}
if (!hdr.hasSupportedCompressionMethod())
{
throw ZipException(Poco::format("Unsupported compression method (%d)", static_cast<int>(hdr.getCompressionMethod())), fileName);
}
Poco::Path file(fileName);
file.makeFile();
Poco::Path dest(_outDir, file);
dest.makeFile();
if (dest.depth() > 0)
{
Poco::File aFile(dest.parent());
aFile.createDirectories();
}
Poco::FileOutputStream out(dest.toString());
ZipInputStream inp(zipStream, hdr, false);
Poco::StreamCopier::copyStream(inp, out);
out.close();
Poco::File aFile(dest.toString());
if (!aFile.exists() || !aFile.isFile())
{
std::pair<const ZipLocalFileHeader, const std::string> tmp = std::make_pair(hdr, "Failed to create output stream " + dest.toString());
EError.notify(this, tmp);
return false;
}
if (!inp.crcValid())
{
if (!_keepIncompleteFiles)
aFile.remove();
std::pair<const ZipLocalFileHeader, const std::string> tmp = std::make_pair(hdr, "CRC mismatch. Corrupt file: " + dest.toString());
EError.notify(this, tmp);
return false;
}
// cannot check against hdr.getUnCompressedSize if CRC and size are not set in hdr but in a ZipDataInfo
// crc is typically enough to detect errors
if (aFile.getSize() != hdr.getUncompressedSize() && !hdr.searchCRCAndSizesAfterData())
{
if (!_keepIncompleteFiles)
aFile.remove();
std::pair<const ZipLocalFileHeader, const std::string> tmp = std::make_pair(hdr, "Filesizes do not match. Corrupt file: " + dest.toString());
EError.notify(this, tmp);
return false;
}
std::pair<const ZipLocalFileHeader, const Poco::Path> tmp = std::make_pair(hdr, file);
EOk.notify(this, tmp);
}
catch (Poco::Exception& e)
{
std::pair<const ZipLocalFileHeader, const std::string> tmp = std::make_pair(hdr, std::string("Exception: " + e.displayText()));
EError.notify(this, tmp);
return false;
}
catch (...)
{
std::pair<const ZipLocalFileHeader, const std::string> tmp = std::make_pair(hdr, std::string("Unknown Exception"));
EError.notify(this, tmp);
return false;
}
return true;
}
void Decompress::onOk(const void*, std::pair<const ZipLocalFileHeader, const Poco::Path>& val)
{
_mapping.insert(std::make_pair(val.first.getFileName(), val.second));
}
} } // namespace Poco::Zip

34
vendor/POCO/Zip/src/Delete.cpp vendored Normal file
View File

@@ -0,0 +1,34 @@
//
// Delete.cpp
//
// Library: Zip
// Package: Manipulation
// Module: Delete
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Delete.h"
namespace Poco {
namespace Zip {
Delete::Delete(const ZipLocalFileHeader& hdr):
_hdr(hdr)
{
}
void Delete::execute(Compress& c, std::istream& input)
{
// due to absolute positioning in compress we don't need to do anything
}
} } // namespace Poco::Zip

37
vendor/POCO/Zip/src/Keep.cpp vendored Normal file
View File

@@ -0,0 +1,37 @@
//
// Keep.cpp
//
// Library: Zip
// Package: Manipulation
// Module: Keep
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Keep.h"
#include "Poco/Zip/Compress.h"
#include "Poco/Buffer.h"
#include "Poco/StreamCopier.h"
namespace Poco {
namespace Zip {
Keep::Keep(const ZipLocalFileHeader& hdr):
_hdr(hdr)
{
}
void Keep::execute(Compress& c, std::istream& input)
{
c.addFileRaw(input, _hdr, _hdr.getFileName());
}
} } // namespace Poco::Zip

32
vendor/POCO/Zip/src/ParseCallback.cpp vendored Normal file
View File

@@ -0,0 +1,32 @@
//
// ParseCallback.cpp
//
// Library: Zip
// Package: Zip
// Module: ParseCallback
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ParseCallback.h"
namespace Poco {
namespace Zip {
ParseCallback::ParseCallback()
{
}
ParseCallback::~ParseCallback()
{
}
} } // namespace Poco::Zip

255
vendor/POCO/Zip/src/PartialStream.cpp vendored Normal file
View File

@@ -0,0 +1,255 @@
//
// PartialStream.cpp
//
// Library: Zip
// Package: Zip
// Module: PartialStream
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/PartialStream.h"
#include "Poco/Exception.h"
#include <cstring>
namespace Poco {
namespace Zip {
PartialStreamBuf::PartialStreamBuf(std::istream& in, std::ios::pos_type start, std::ios::pos_type end, const std::string& pre, const std::string& post, bool initStream):
Poco::BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
_initialized(!initStream),
_start(start),
_numBytes(end-start),
_bytesWritten(0),
_pIstr(&in),
_pOstr(0),
_prefix(pre),
_postfix(post),
_ignoreStart(0),
_buffer(0),
_bufferOffset(0)
{
}
PartialStreamBuf::PartialStreamBuf(std::ostream& out, std::size_t start, std::size_t end, bool initStream):
Poco::BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
_initialized(!initStream),
_start(0),
_numBytes(0),
_bytesWritten(0),
_pIstr(0),
_pOstr(&out),
_ignoreStart(start),
_buffer(end),
_bufferOffset(0)
{
}
PartialStreamBuf::~PartialStreamBuf()
{
}
int PartialStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
if (_pIstr == 0 ||length == 0) return -1;
if (!_initialized)
{
_initialized = true;
_pIstr->clear();
_pIstr->seekg(_start, std::ios_base::beg);
if (_pIstr->fail())
throw Poco::IOException("Failed to seek on input stream");
}
if (!_prefix.empty())
{
std::streamsize tmp = (_prefix.size() > length)? length: static_cast<std::streamsize>(_prefix.size());
std::memcpy(buffer, _prefix.c_str(), tmp);
_prefix = _prefix.substr(tmp);
return static_cast<int>(tmp);
}
if (_numBytes == 0)
{
if (!_postfix.empty())
{
std::streamsize tmp = (_postfix.size() > length)? length: static_cast<std::streamsize>(_postfix.size());
std::memcpy(buffer, _postfix.c_str(), tmp);
_postfix = _postfix.substr(tmp);
return static_cast<int>(tmp);
}
else
return -1;
}
if (!_pIstr->good())
return -1;
if (_numBytes < length)
length = static_cast<std::streamsize>(_numBytes);
_pIstr->read(buffer, length);
std::streamsize bytesRead = _pIstr->gcount();
_numBytes -= bytesRead;
return static_cast<int>(bytesRead);
}
int PartialStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
{
if (_pOstr == 0 || length == 0) return -1;
if (!_initialized)
{
_initialized = true;
_pOstr->clear();
if (_pOstr->fail())
throw Poco::IOException("Failed to clear stream status");
}
if (_ignoreStart > 0)
{
if (_ignoreStart > length)
{
_ignoreStart -= length;
// fake return values
return static_cast<int>(length);
}
else
{
std::streamsize cnt = static_cast<std::streamsize>(length - _ignoreStart - _buffer.size());
if (cnt > 0)
{
_pOstr->write(buffer+_ignoreStart, cnt);
_bytesWritten += cnt;
}
// copy the rest into buffer
cnt += static_cast<std::streamsize>(_ignoreStart);
_ignoreStart = 0;
poco_assert (cnt < length);
_bufferOffset = static_cast<Poco::UInt32>(length - cnt);
std::memcpy(_buffer.begin(), buffer + cnt, _bufferOffset);
return static_cast<int>(length);
}
}
if (_buffer.size() > 0)
{
// always treat each write as the potential last one
// thus first fill the buffer with the last n bytes of the msg
// how much of the already cached data do we need to write?
Poco::Int32 cache = static_cast<Poco::Int32>(_bufferOffset +
static_cast<Poco::Int32>(length) - static_cast<Poco::Int32>(_buffer.size()));
if (cache > 0)
{
if (cache > _bufferOffset)
cache = _bufferOffset;
_pOstr->write(_buffer.begin(), cache);
_bytesWritten += cache;
_bufferOffset -= cache;
if (_bufferOffset > 0)
std::memmove(_buffer.begin(), _buffer.begin()+cache, _bufferOffset);
}
// now fill up _buffer with the last bytes from buffer
Poco::Int32 pos = static_cast<Poco::Int32>(length - static_cast<Poco::Int32>(_buffer.size()) + _bufferOffset);
if (pos <= 0)
{
// all of the message goes to _buffer
std::memcpy(_buffer.begin() + _bufferOffset, buffer, length);
}
else
{
poco_assert (_bufferOffset == 0);
std::memcpy(_buffer.begin(), buffer+pos, _buffer.size());
_bufferOffset = static_cast<Poco::UInt32>(_buffer.size());
// the rest is written
_pOstr->write(buffer, static_cast<std::streamsize>(length - _buffer.size()));
_bytesWritten += (length - _buffer.size());
}
}
else
{
_pOstr->write(buffer, length);
_bytesWritten += length;
}
if (_pOstr->good())
return static_cast<int>(length);
throw Poco::IOException("Failed to write to output stream");
}
void PartialStreamBuf::close()
{
// DON'T write data from _buffer!
}
PartialIOS::PartialIOS(std::istream& istr, std::ios::pos_type start, std::ios::pos_type end, const std::string& pre, const std::string& post, bool initStream): _buf(istr, start, end, pre, post, initStream)
{
poco_ios_init(&_buf);
}
PartialIOS::PartialIOS(std::ostream& ostr, std::size_t start, std::size_t end, bool initStream): _buf(ostr, start, end, initStream)
{
poco_ios_init(&_buf);
}
PartialIOS::~PartialIOS()
{
}
PartialStreamBuf* PartialIOS::rdbuf()
{
return &_buf;
}
PartialInputStream::PartialInputStream(std::istream& istr, std::ios::pos_type start, std::ios::pos_type end, bool initStream, const std::string& pre, const std::string& post):
PartialIOS(istr, start, end, pre, post, initStream),
std::istream(&_buf)
{
}
PartialInputStream::~PartialInputStream()
{
}
PartialOutputStream::PartialOutputStream(std::ostream& ostr, std::size_t start, std::size_t end, bool initStream):
PartialIOS(ostr, start, end, initStream),
std::ostream(&_buf)
{
}
PartialOutputStream::~PartialOutputStream()
{
try
{
close();
}
catch (...)
{
poco_unexpected();
}
}
} } // namespace Poco::Zip

36
vendor/POCO/Zip/src/Rename.cpp vendored Normal file
View File

@@ -0,0 +1,36 @@
//
// Rename.cpp
//
// Library: Zip
// Package: Manipulation
// Module: Rename
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Rename.h"
#include "Poco/Zip/Compress.h"
namespace Poco {
namespace Zip {
Rename::Rename(const ZipLocalFileHeader& hdr, const std::string& newZipEntryName):
_hdr(hdr),
_newZipEntryName(newZipEntryName)
{
}
void Rename::execute(Compress& c, std::istream& input)
{
c.addFileRaw(input, _hdr, _newZipEntryName);
}
} } // namespace Poco::Zip

37
vendor/POCO/Zip/src/Replace.cpp vendored Normal file
View File

@@ -0,0 +1,37 @@
//
// Replace.cpp
//
// Library: Zip
// Package: Manipulation
// Module: Replace
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/Replace.h"
#include "Poco/Zip/Compress.h"
namespace Poco {
namespace Zip {
Replace::Replace(const ZipLocalFileHeader& hdr, const std::string& localPath):
_del(hdr),
_add(hdr.getFileName(), localPath, hdr.getCompressionMethod(), hdr.getCompressionLevel())
{
}
void Replace::execute(Compress& c, std::istream& input)
{
_del.execute(c, input);
_add.execute(c, input);
}
} } // namespace Poco::Zip

46
vendor/POCO/Zip/src/SkipCallback.cpp vendored Normal file
View File

@@ -0,0 +1,46 @@
//
// SkipCallback.cpp
//
// Library: Zip
// Package: Zip
// Module: SkipCallback
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/SkipCallback.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipUtil.h"
#include "Poco/Exception.h"
namespace Poco {
namespace Zip {
SkipCallback::SkipCallback()
{
}
SkipCallback::~SkipCallback()
{
}
bool SkipCallback::handleZipEntry(std::istream& zipStream, const ZipLocalFileHeader& hdr)
{
if (!hdr.searchCRCAndSizesAfterData())
zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
else
ZipUtil::syncDataDescriptor(zipStream, hdr.needsZip64());
if (!zipStream.good()) throw Poco::IOException("Failed to seek on input stream");
return true;
}
} } // namespace Poco::Zip

144
vendor/POCO/Zip/src/ZipArchive.cpp vendored Normal file
View File

@@ -0,0 +1,144 @@
//
// ZipArchive.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipArchive
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipArchive.h"
#include "Poco/Zip/SkipCallback.h"
#include "Poco/Exception.h"
#include <cstring>
namespace Poco {
namespace Zip {
const std::string ZipArchive::EMPTY_COMMENT;
ZipArchive::ZipArchive(std::istream& in):
_entries(),
_infos(),
_disks(),
_disks64()
{
poco_assert_dbg (in);
SkipCallback skip;
parse(in, skip);
}
ZipArchive::ZipArchive(const FileHeaders& entries, const FileInfos& infos, const DirectoryInfos& dirs, const DirectoryInfos64& dirs64):
_entries(entries),
_infos(infos),
_disks(dirs),
_disks64(dirs64)
{
}
ZipArchive::ZipArchive(std::istream& in, ParseCallback& pc):
_entries(),
_infos(),
_disks(),
_disks64()
{
poco_assert_dbg (in);
parse(in, pc);
}
ZipArchive::~ZipArchive()
{
}
void ZipArchive::parse(std::istream& in, ParseCallback& pc)
{
// read 4 bytes
bool haveSynced = false;
while (in.good() && !in.eof())
{
char header[ZipCommon::HEADER_SIZE]={'\x00', '\x00', '\x00', '\x00'};
in.read(header, ZipCommon::HEADER_SIZE);
if (in.eof())
return;
if (std::memcmp(header, ZipLocalFileHeader::HEADER, ZipCommon::HEADER_SIZE) == 0)
{
ZipLocalFileHeader entry(in, true, pc);
poco_assert (_entries.insert(std::make_pair(entry.getFileName(), entry)).second);
haveSynced = false;
}
else if (std::memcmp(header, ZipFileInfo::HEADER, ZipCommon::HEADER_SIZE) == 0)
{
ZipFileInfo info(in, true);
FileHeaders::iterator it = _entries.find(info.getFileName());
if (it != _entries.end())
{
it->second.setStartPos(info.getOffset());
}
poco_assert (_infos.insert(std::make_pair(info.getFileName(), info)).second);
haveSynced = false;
}
else if (std::memcmp(header, ZipArchiveInfo::HEADER, ZipCommon::HEADER_SIZE) == 0)
{
ZipArchiveInfo nfo(in, true);
poco_assert (_disks.insert(std::make_pair(nfo.getDiskNumber(), nfo)).second);
haveSynced = false;
}
else if (std::memcmp(header, ZipArchiveInfo64::HEADER, ZipCommon::HEADER_SIZE) == 0)
{
ZipArchiveInfo64 nfo(in, true);
poco_assert (_disks64.insert(std::make_pair(nfo.getDiskNumber(), nfo)).second);
haveSynced = false;
}
else
{
if (!haveSynced)
{
// Some Zip files have extra data behind the ZipLocalFileHeader.
// Try to re-sync.
ZipUtil::sync(in);
haveSynced = true;
}
else
{
if (_disks.empty() && _disks64.empty())
throw Poco::IllegalStateException("Illegal header in zip file");
else
throw Poco::IllegalStateException("Garbage after directory header");
}
}
}
}
const std::string& ZipArchive::getZipComment() const
{
// It seems that only the "first" disk is populated (look at Compress::close()), so getting the first ZipArchiveInfo
DirectoryInfos::const_iterator it = _disks.begin();
if (it != _disks.end())
{
return it->second.getZipComment();
}
else
{
DirectoryInfos64::const_iterator it64 = _disks64.begin();
if (it64 != _disks64.end())
return it->second.getZipComment();
else
return EMPTY_COMMENT;
}
}
} } // namespace Poco::Zip

190
vendor/POCO/Zip/src/ZipArchiveInfo.cpp vendored Normal file
View File

@@ -0,0 +1,190 @@
//
// ZipArchiveInfo.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipArchiveInfo
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipArchiveInfo.h"
#include "Poco/Zip/ZipException.h"
#include "Poco/Buffer.h"
#include <istream>
#include <cstring>
namespace Poco {
namespace Zip {
const char ZipArchiveInfo::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x05', '\x06'};
ZipArchiveInfo::ZipArchiveInfo(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_startPos(in.tellg()),
_comment()
{
if (assumeHeaderRead)
_startPos -= ZipCommon::HEADER_SIZE;
parse(in, assumeHeaderRead);
}
ZipArchiveInfo::ZipArchiveInfo():
_rawInfo(),
_startPos(0),
_comment()
{
std::memset(_rawInfo, 0, FULLHEADER_SIZE);
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
ZipArchiveInfo::~ZipArchiveInfo()
{
}
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);
}
// read the rest of the header
inp.read(_rawInfo + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
Poco::UInt16 len = getZipCommentSize();
if (len > 0)
{
Poco::Buffer<char> buf(len);
inp.read(buf.begin(), len);
_comment = std::string(buf.begin(), len);
}
}
std::string ZipArchiveInfo::createHeader() const
{
std::string result(_rawInfo, FULLHEADER_SIZE);
result.append(_comment);
return result;
}
void ZipArchiveInfo::setZipComment(const std::string& comment)
{
// Confirm string is of valid size
if (comment.size() > 65535)
throw ZipException("Maximum number of entries for a ZIP file reached: 65535");
// Change the value of the ZIP Comment Size to reflect new comment size
ZipUtil::set16BitValue(static_cast<Poco::UInt16>(comment.size()), _rawInfo, ZIPCOMMENT_LENGTH_POS);
// Now change our internal comment
_comment = comment;
}
const char ZipArchiveInfo64::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x06', '\x06'};
const char ZipArchiveInfo64::LOCATOR_HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x06', '\x07'};
ZipArchiveInfo64::ZipArchiveInfo64(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_startPos(in.tellg())
{
if (assumeHeaderRead)
_startPos -= ZipCommon::HEADER_SIZE;
parse(in, assumeHeaderRead);
}
ZipArchiveInfo64::ZipArchiveInfo64():
_rawInfo(),
_startPos(0)
{
std::memset(_rawInfo, 0, FULL_HEADER_SIZE);
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
ZipUtil::set64BitValue(FULL_HEADER_SIZE - (RECORDSIZE_POS + RECORDSIZE_SIZE), _rawInfo, RECORDSIZE_POS);
std::memset(_locInfo, 0, FULL_LOCATOR_SIZE);
std::memcpy(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE);
setRequiredVersion(4, 5);
}
ZipArchiveInfo64::~ZipArchiveInfo64()
{
}
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);
}
std::memset(_rawInfo + ZipCommon::HEADER_SIZE, 0, FULL_HEADER_SIZE - ZipCommon::HEADER_SIZE);
// read the rest of the header
Poco::UInt64 offset = RECORDSIZE_POS;
inp.read(_rawInfo + ZipCommon::HEADER_SIZE, RECORDSIZE_SIZE);
offset += RECORDSIZE_SIZE;
Poco::UInt64 len = ZipUtil::get64BitValue(_rawInfo, RECORDSIZE_POS);
if (len <= FULL_HEADER_SIZE - offset)
{
inp.read(_rawInfo + offset, len);
ZipUtil::set64BitValue(FULL_HEADER_SIZE - offset, _rawInfo, RECORDSIZE_POS);
}
else
{
inp.read(_rawInfo + offset, FULL_HEADER_SIZE - offset);
len -= (FULL_HEADER_SIZE - offset);
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
ZipUtil::set64BitValue(FULL_HEADER_SIZE + len - offset, _rawInfo, RECORDSIZE_POS);
}
inp.read(_locInfo, FULL_LOCATOR_SIZE);
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");
}
std::string ZipArchiveInfo64::createHeader() const
{
std::string result(_rawInfo, FULL_HEADER_SIZE);
result.append(_extraField);
result.append(_locInfo, FULL_LOCATOR_SIZE);
return result;
}
} } // namespace Poco::Zip

56
vendor/POCO/Zip/src/ZipCommon.cpp vendored Normal file
View File

@@ -0,0 +1,56 @@
//
// ZipCommon.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipCommon
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipCommon.h"
#include "Poco/Path.h"
namespace Poco {
namespace Zip {
bool ZipCommon::isValidPath(const std::string& path)
{
try
{
if (Path(path, Path::PATH_UNIX).isAbsolute() || Path(path, Path::PATH_WINDOWS).isAbsolute())
return false;
}
catch (...)
{
return false;
}
if (path == "..")
return false;
if ((path.size() >= 3) && path.compare(0, 3, "../") == 0)
return false;
if ((path.size() >= 3) && path.compare(0, 3, "..\\") == 0)
return false;
if (path.find("/../") != std::string::npos)
return false;
if (path.find("\\..\\") != std::string::npos)
return false;
if (path.find("/..\\") != std::string::npos)
return false;
if (path.find("\\../") != std::string::npos)
return false;
if ((path.size() >= 2) && path.compare(0, 2, "~/") == 0)
return false;
return true;
}
} } // namespace Poco::Zip

106
vendor/POCO/Zip/src/ZipDataInfo.cpp vendored Normal file
View File

@@ -0,0 +1,106 @@
//
// ZipDataInfo.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipDataInfo
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Exception.h"
#include <istream>
#include <cstring>
namespace Poco {
namespace Zip {
const char ZipDataInfo::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x07', '\x08'};
ZipDataInfo::ZipDataInfo():
_rawInfo(),
_valid(true)
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
std::memset(_rawInfo+ZipCommon::HEADER_SIZE, 0, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = true;
}
ZipDataInfo::ZipDataInfo(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_valid(false)
{
if (assumeHeaderRead)
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
else
{
in.read(_rawInfo, ZipCommon::HEADER_SIZE);
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");
}
// now copy the rest of the header
in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = (!in.eof() && in.good());
}
ZipDataInfo::~ZipDataInfo()
{
}
const char ZipDataInfo64::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x07', '\x08'};
ZipDataInfo64::ZipDataInfo64():
_rawInfo(),
_valid(true)
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
std::memset(_rawInfo+ZipCommon::HEADER_SIZE, 0, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = true;
}
ZipDataInfo64::ZipDataInfo64(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_valid(false)
{
if (assumeHeaderRead)
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
else
{
in.read(_rawInfo, ZipCommon::HEADER_SIZE);
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");
}
// now copy the rest of the header
in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = (!in.eof() && in.good());
}
ZipDataInfo64::~ZipDataInfo64()
{
}
} } // namespace Poco::Zip

27
vendor/POCO/Zip/src/ZipException.cpp vendored Normal file
View File

@@ -0,0 +1,27 @@
//
// ZipException.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipException
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipException.h"
#include <typeinfo>
namespace Poco {
namespace Zip {
POCO_IMPLEMENT_EXCEPTION(ZipException, Poco::RuntimeException, "ZIP Exception")
POCO_IMPLEMENT_EXCEPTION(ZipManipulationException, ZipException, "ZIP Manipulation Exception")
} } // namespace Poco::Zip

188
vendor/POCO/Zip/src/ZipFileInfo.cpp vendored Normal file
View File

@@ -0,0 +1,188 @@
//
// ZipFileInfo.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipFileInfo
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipFileInfo.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Buffer.h"
#include <istream>
#include <cstring>
namespace Poco {
namespace Zip {
const char ZipFileInfo::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x01', '\x02'};
ZipFileInfo::ZipFileInfo(const ZipLocalFileHeader& header):
_rawInfo(),
_crc32(0),
_compressedSize(0),
_uncompressedSize(0),
_localHeaderOffset(0),
_fileName(),
_lastModifiedAt(),
_extraField()
{
std::memset(_rawInfo, 0, FULLHEADER_SIZE);
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
setCompressedSize(header.getCompressedSize());
setUncompressedSize(header.getUncompressedSize());
setCRC(header.getCRC());
setCompressionMethod(header.getCompressionMethod());
setCompressionLevel(header.getCompressionLevel());
setRequiredVersion(header.getMajorVersionNumber(), header.getMinorVersionNumber());
setHostSystem(header.getHostSystem());
setLastModifiedAt(header.lastModifiedAt());
setEncryption(false);
setFileName(header.getFileName());
if (getHostSystem() == ZipCommon::HS_UNIX)
setUnixAttributes();
_rawInfo[GENERAL_PURPOSE_POS+1] |= 0x08; // Set "language encoding flag" to indicate that filenames and paths are in UTF-8.
if (header.searchCRCAndSizesAfterData())
_rawInfo[GENERAL_PURPOSE_POS] |= 0x08;
}
ZipFileInfo::ZipFileInfo(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_crc32(0),
_compressedSize(0),
_uncompressedSize(0),
_localHeaderOffset(0),
_fileName(),
_lastModifiedAt(),
_extraField()
{
// sanity check
poco_assert_dbg (RELATIVEOFFSETLOCALHEADER_POS + RELATIVEOFFSETLOCALHEADER_SIZE == FULLHEADER_SIZE);
parse(in, assumeHeaderRead);
}
ZipFileInfo::~ZipFileInfo()
{
}
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);
}
// read the rest of the header
inp.read(_rawInfo + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_crc32 = getCRCFromHeader();
_compressedSize = getCompressedSizeFromHeader();
_uncompressedSize = getUncompressedSizeFromHeader();
_localHeaderOffset = getOffsetFromHeader();
parseDateTime();
Poco::UInt16 len = getFileNameLength();
if (len > 0)
{
Poco::Buffer<char> buf(len);
inp.read(buf.begin(), len);
_fileName = std::string(buf.begin(), len);
}
if (hasExtraField())
{
len = getExtraFieldLength();
if (len > 0)
{
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
char* ptr = xtra.begin();
while (ptr <= xtra.begin() + len - 4)
{
Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0);
ptr += 2;
Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0);
ptr += 2;
if (id == ZipCommon::ZIP64_EXTRA_ID)
{
if (size >= 8 && getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setUncompressedSize(ZipUtil::get64BitValue(ptr, 0));
size -= 8;
ptr += 8;
}
if (size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setCompressedSize(ZipUtil::get64BitValue(ptr, 0));
size -= 8;
ptr += 8;
}
if (size >= 8 && getOffsetFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setOffset(ZipUtil::get64BitValue(ptr, 0));
size -= 8;
ptr += 8;
}
}
else
{
ptr += size;
}
}
}
}
len = getFileCommentLength();
if (len > 0)
{
Poco::Buffer<char> buf2(len);
inp.read(buf2.begin(), len);
_fileComment = std::string(buf2.begin(), len);
}
}
std::string ZipFileInfo::createHeader() const
{
std::string result(_rawInfo, FULLHEADER_SIZE);
result.append(_fileName);
result.append(_extraField);
result.append(_fileComment);
return result;
}
void ZipFileInfo::setUnixAttributes()
{
bool isDir = isDirectory();
int mode;
if (isDir)
mode = DEFAULT_UNIX_DIR_MODE;
else
mode = DEFAULT_UNIX_FILE_MODE;
Poco::UInt32 attrs = (mode << 16) | (isDir ? 0x10 : 0);
setExternalFileAttributes(attrs);
}
} } // namespace Poco::Zip

View File

@@ -0,0 +1,262 @@
//
// ZipLocalFileHeader.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipLocalFileHeader
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Zip/ParseCallback.h"
#include "Poco/Buffer.h"
#include "Poco/Exception.h"
#include "Poco/File.h"
#include <cstring>
namespace Poco {
namespace Zip {
const char ZipLocalFileHeader::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x03', '\x04'};
ZipLocalFileHeader::ZipLocalFileHeader(const Poco::Path& fileName,
const Poco::DateTime& lastModifiedAt,
ZipCommon::CompressionMethod cm,
ZipCommon::CompressionLevel cl,
bool forceZip64):
_forceZip64(forceZip64),
_rawHeader(),
_startPos(-1),
_endPos(-1),
_fileName(),
_lastModifiedAt(),
_extraField(),
_crc32(0),
_compressedSize(0),
_uncompressedSize(0)
{
std::memcpy(_rawHeader, HEADER, ZipCommon::HEADER_SIZE);
std::memset(_rawHeader+ZipCommon::HEADER_SIZE, 0, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
setHostSystem(ZipCommon::HS_FAT);
setEncryption(false);
setExtraFieldSize(0);
setLastModifiedAt(lastModifiedAt);
init(fileName, cm, cl);
}
ZipLocalFileHeader::ZipLocalFileHeader(std::istream& inp, bool assumeHeaderRead, ParseCallback& callback):
_forceZip64(false),
_rawHeader(),
_startPos(inp.tellg()),
_endPos(-1),
_fileName(),
_lastModifiedAt(),
_extraField(),
_crc32(0),
_compressedSize(0),
_uncompressedSize(0)
{
poco_assert_dbg( (EXTRA_FIELD_POS+EXTRA_FIELD_LENGTH) == FULLHEADER_SIZE);
if (assumeHeaderRead)
_startPos -= ZipCommon::HEADER_SIZE;
parse(inp, assumeHeaderRead);
bool ok = callback.handleZipEntry(inp, *this);
if (ok)
{
if (searchCRCAndSizesAfterData())
{
char header[ZipCommon::HEADER_SIZE]={'\x00', '\x00', '\x00', '\x00'};
inp.read(header, ZipCommon::HEADER_SIZE);
if (_forceZip64)
{
ZipDataInfo64 nfo(inp, true);
setCRC(nfo.getCRC32());
setCompressedSize(nfo.getCompressedSize());
setUncompressedSize(nfo.getUncompressedSize());
}
else
{
ZipDataInfo nfo(inp, true);
setCRC(nfo.getCRC32());
setCompressedSize(nfo.getCompressedSize());
setUncompressedSize(nfo.getUncompressedSize());
}
}
}
else
{
poco_assert_dbg(!searchCRCAndSizesAfterData());
ZipUtil::sync(inp);
}
_endPos = _startPos + getHeaderSize() + _compressedSize; // exclude the data block!
}
ZipLocalFileHeader::~ZipLocalFileHeader()
{
}
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);
}
// 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
poco_assert (ZipUtil::get16BitValue(_rawHeader, COMPR_METHOD_POS) < ZipCommon::CM_UNUSED);
parseDateTime();
Poco::UInt16 len = getFileNameLength();
if (len > 0)
{
Poco::Buffer<char> buf(len);
inp.read(buf.begin(), len);
_fileName = std::string(buf.begin(), len);
}
if (!searchCRCAndSizesAfterData())
{
_crc32 = getCRCFromHeader();
_compressedSize = getCompressedSizeFromHeader();
_uncompressedSize = getUncompressedSizeFromHeader();
}
if (hasExtraField())
{
len = getExtraFieldLength();
if (len > 0)
{
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
char* ptr = xtra.begin();
while (ptr <= xtra.begin() + len - 4)
{
Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0);
ptr += 2;
Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0);
ptr += 2;
if (id == ZipCommon::ZIP64_EXTRA_ID)
{
_forceZip64 = true;
if (size >= 8 && getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setUncompressedSize(ZipUtil::get64BitValue(ptr, 0));
size -= 8;
ptr += 8;
}
if (size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setCompressedSize(ZipUtil::get64BitValue(ptr, 0));
size -= 8;
ptr += 8;
}
}
else
{
ptr += size;
}
}
}
}
}
bool ZipLocalFileHeader::searchCRCAndSizesAfterData() const
{
if (getCompressionMethod() == ZipCommon::CM_STORE || getCompressionMethod() == ZipCommon::CM_DEFLATE)
{
// check bit 3
return ((ZipUtil::get16BitValue(_rawHeader, GENERAL_PURPOSE_POS) & 0x0008) != 0);
}
return false;
}
void ZipLocalFileHeader::setFileName(const std::string& fileName, bool isDirectory)
{
poco_assert (!fileName.empty());
Poco::Path aPath(fileName);
if (isDirectory)
{
aPath.makeDirectory();
setCRC(0);
setCompressedSize(0);
setUncompressedSize(0);
setCompressionMethod(ZipCommon::CM_STORE);
setCompressionLevel(ZipCommon::CL_NORMAL);
}
else
{
aPath.makeFile();
}
_fileName = aPath.toString(Poco::Path::PATH_UNIX);
if (_fileName[0] == '/')
_fileName = _fileName.substr(1);
if (isDirectory)
{
poco_assert_dbg (_fileName[_fileName.size()-1] == '/');
}
setFileNameLength(static_cast<Poco::UInt16>(_fileName.size()));
}
void ZipLocalFileHeader::init(const Poco::Path& fName, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
{
poco_assert (_fileName.empty());
setSearchCRCAndSizesAfterData(false);
Poco::Path fileName(fName);
fileName.setDevice(""); // clear device!
setFileName(fileName.toString(Poco::Path::PATH_UNIX), fileName.isDirectory());
setRequiredVersion(2, 0);
if (fileName.isFile())
{
setCompressionMethod(cm);
setCompressionLevel(cl);
}
else
setCompressionMethod(ZipCommon::CM_STORE);
if (_forceZip64)
setZip64Data();
_rawHeader[GENERAL_PURPOSE_POS+1] |= 0x08; // Set "language encoding flag" to indicate that filenames and paths are in UTF-8.
}
std::string ZipLocalFileHeader::createHeader() const
{
std::string result(_rawHeader, FULLHEADER_SIZE);
result.append(_fileName);
result.append(_extraField);
return result;
}
} } // namespace Poco::Zip

171
vendor/POCO/Zip/src/ZipManipulator.cpp vendored Normal file
View File

@@ -0,0 +1,171 @@
//
// ZipManipulator.cpp
//
// Library: Zip
// Package: Manipulation
// Module: ZipManipulator
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipManipulator.h"
#include "Poco/Zip/ZipException.h"
#include "Poco/Zip/ZipUtil.h"
#include "Poco/Zip/Add.h"
#include "Poco/Zip/Delete.h"
#include "Poco/Zip/Keep.h"
#include "Poco/Zip/Rename.h"
#include "Poco/Zip/Replace.h"
#include "Poco/Zip/Compress.h"
#include "Poco/Delegate.h"
#include "Poco/File.h"
#include "Poco/FileStream.h"
namespace Poco {
namespace Zip {
ZipManipulator::ZipManipulator(const std::string& zipFile, bool backupOriginalFile):
_zipFile(zipFile),
_backupOriginalFile(backupOriginalFile),
_changes(),
_in(0)
{
Poco::FileInputStream in(zipFile);
_in = new ZipArchive(in);
}
ZipManipulator::~ZipManipulator()
{
}
void ZipManipulator::deleteFile(const std::string& zipPath)
{
const ZipLocalFileHeader& entry = getForChange(zipPath);
addOperation(zipPath, new Delete(entry));
}
void ZipManipulator::replaceFile(const std::string& zipPath, const std::string& localPath)
{
const ZipLocalFileHeader& entry = getForChange(zipPath);
addOperation(zipPath, new Replace(entry, localPath));
}
void ZipManipulator::renameFile(const std::string& zipPath, const std::string& newZipPath)
{
const ZipLocalFileHeader& entry = getForChange(zipPath);
// checked later in Compress too but the earlier one gets the error the better
std::string fn = ZipUtil::validZipEntryFileName(newZipPath);
addOperation(zipPath, new Rename(entry, fn));
}
void ZipManipulator::addFile(const std::string& zipPath, const std::string& localPath, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
{
addOperation(zipPath, new Add(zipPath, localPath, cm, cl));
}
ZipArchive ZipManipulator::commit()
{
// write to a tmp file
std::string outFile(_zipFile + ".tmp");
ZipArchive retVal(compress(outFile));
//renaming
{
Poco::File aFile(_zipFile);
if (_backupOriginalFile)
{
Poco::File tmp(_zipFile+".bak");
if (tmp.exists())
tmp.remove();
aFile.renameTo(_zipFile+".bak");
}
else
aFile.remove();
}
{
Poco::File resFile(outFile);
Poco::File zipFile(_zipFile);
if (zipFile.exists())
zipFile.remove();
resFile.renameTo(_zipFile);
}
return retVal;
}
const ZipLocalFileHeader& ZipManipulator::getForChange(const std::string& zipPath) const
{
ZipArchive::FileHeaders::const_iterator it = _in->findHeader(zipPath);
if (it == _in->headerEnd())
throw ZipManipulationException("Entry not found: " + zipPath);
if (_changes.find(zipPath) != _changes.end())
throw ZipManipulationException("A change request exists already for entry " + zipPath);
return it->second;
}
void ZipManipulator::addOperation(const std::string& zipPath, ZipOperation::Ptr ptrOp)
{
std::pair<Changes::iterator, bool> result = _changes.insert(std::make_pair(zipPath, ptrOp));
if (!result.second)
throw ZipManipulationException("A change request exists already for entry " + zipPath);
}
void ZipManipulator::onEDone(const void*, const ZipLocalFileHeader& hdr)
{
EDone(this, hdr);
}
ZipArchive ZipManipulator::compress(const std::string& outFile)
{
// write to a tmp file
Poco::FileInputStream in(_zipFile);
Poco::FileOutputStream out(outFile);
Compress c(out, true);
c.EDone += Poco::Delegate<ZipManipulator, const ZipLocalFileHeader>(this, &ZipManipulator::onEDone);
ZipArchive::FileHeaders::const_iterator it = _in->headerBegin();
for (; it != _in->headerEnd(); ++it)
{
Changes::iterator itC = _changes.find(it->first);
if (itC != _changes.end())
{
itC->second->execute(c, in);
_changes.erase(itC);
}
else
{
Keep k(it->second);
k.execute(c, in);
}
}
//Remaining files are add operations!
Changes::iterator itC = _changes.begin();
for (; itC != _changes.end(); ++itC)
{
itC->second->execute(c, in);
}
_changes.clear();
c.EDone -= Poco::Delegate<ZipManipulator, const ZipLocalFileHeader>(this, &ZipManipulator::onEDone);
in.close();
return c.close();
}
} } // namespace Poco::Zip

32
vendor/POCO/Zip/src/ZipOperation.cpp vendored Normal file
View File

@@ -0,0 +1,32 @@
//
// ZipOperation.cpp
//
// Library: Zip
// Package: Manipulation
// Module: ZipOperation
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipOperation.h"
namespace Poco {
namespace Zip {
ZipOperation::ZipOperation()
{
}
ZipOperation::~ZipOperation()
{
}
} } // namespace Poco::Zip

337
vendor/POCO/Zip/src/ZipStream.cpp vendored Normal file
View File

@@ -0,0 +1,337 @@
//
// ZipStream.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipStream
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipStream.h"
#include "Poco/Zip/ZipArchive.h"
#include "Poco/Zip/AutoDetectStream.h"
#include "Poco/Zip/PartialStream.h"
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Zip/ZipException.h"
#include "Poco/Exception.h"
#include "Poco/InflatingStream.h"
#include "Poco/DeflatingStream.h"
#include "Poco/Format.h"
#if defined(POCO_UNBUNDLED)
#include <zlib.h>
#else
#include "Poco/zlib.h"
#endif
namespace Poco {
namespace Zip {
ZipStreamBuf::ZipStreamBuf(std::istream& istr, const ZipLocalFileHeader& fileEntry, bool reposition):
Poco::BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
_pIstr(&istr),
_pOstr(0),
_ptrBuf(),
_ptrOBuf(),
_ptrHelper(),
_ptrOHelper(),
_crc32(Poco::Checksum::TYPE_CRC32),
_expectedCrc32(0),
_checkCRC(true),
_bytesWritten(0),
_pHeader(0)
{
if (fileEntry.isDirectory())
return;
_expectedCrc32 = fileEntry.getCRC();
std::streamoff start = fileEntry.getDataStartPos();
std::streamoff end = fileEntry.getDataEndPos();
_checkCRC = !fileEntry.searchCRCAndSizesAfterData();
if (fileEntry.getCompressionMethod() == ZipCommon::CM_DEFLATE)
{
// Fake init bytes at beginning of stream
std::string init = ZipUtil::fakeZLibInitString(fileEntry.getCompressionLevel());
// Fake adler at end of stream: just some dummy value, not checked anway
std::string crc(4, ' ');
if (fileEntry.searchCRCAndSizesAfterData())
{
_ptrHelper = new AutoDetectInputStream(istr, init, crc, reposition, static_cast<Poco::UInt32>(start), fileEntry.needsZip64());
}
else
{
_ptrHelper = new PartialInputStream(istr, start, end, reposition, init, crc);
}
_ptrBuf = new Poco::InflatingInputStream(*_ptrHelper, Poco::InflatingStreamBuf::STREAM_ZIP);
}
else if (fileEntry.getCompressionMethod() == ZipCommon::CM_STORE)
{
if (fileEntry.searchCRCAndSizesAfterData())
{
_ptrBuf = new AutoDetectInputStream(istr, "", "", reposition, static_cast<Poco::UInt32>(start), fileEntry.needsZip64());
}
else
{
_ptrBuf = new PartialInputStream(istr, start, end, reposition);
}
}
}
ZipStreamBuf::ZipStreamBuf(std::ostream& ostr, ZipLocalFileHeader& fileEntry, bool reposition):
Poco::BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
_pIstr(0),
_pOstr(&ostr),
_ptrBuf(),
_ptrOBuf(),
_ptrHelper(),
_ptrOHelper(),
_crc32(Poco::Checksum::TYPE_CRC32),
_expectedCrc32(0),
_checkCRC(false),
_bytesWritten(0),
_pHeader(&fileEntry)
{
if (fileEntry.isEncrypted())
throw Poco::NotImplementedException("Encryption not supported");
if (fileEntry.isDirectory())
{
// only header, no payload, zero crc
fileEntry.setSearchCRCAndSizesAfterData(false);
fileEntry.setCompressedSize(0);
fileEntry.setUncompressedSize(0);
fileEntry.setCRC(0);
std::string header = fileEntry.createHeader();
ostr.write(header.c_str(), static_cast<std::streamsize>(header.size()));
}
else
{
fileEntry.setSearchCRCAndSizesAfterData(!reposition);
if (fileEntry.getCompressionMethod() == ZipCommon::CM_DEFLATE)
{
int level = Z_DEFAULT_COMPRESSION;
if (fileEntry.getCompressionLevel() == ZipCommon::CL_FAST || fileEntry.getCompressionLevel() == ZipCommon::CL_SUPERFAST)
level = Z_BEST_SPEED;
else if (fileEntry.getCompressionLevel() == ZipCommon::CL_MAXIMUM)
level = Z_BEST_COMPRESSION;
// ignore the zlib init string which is of size 2 and also ignore the 4 byte adler32 value at the end of the stream!
_ptrOHelper = new PartialOutputStream(*_pOstr, 2, 4, false);
_ptrOBuf = new Poco::DeflatingOutputStream(*_ptrOHelper, DeflatingStreamBuf::STREAM_ZLIB, level);
}
else if (fileEntry.getCompressionMethod() == ZipCommon::CM_STORE)
{
_ptrOHelper = new PartialOutputStream(*_pOstr, 0, 0, false);
_ptrOBuf = new PartialOutputStream(*_ptrOHelper, 0, 0, false);
}
else throw Poco::NotImplementedException("Unsupported compression method");
// now write the header to the ostr!
if (fileEntry.needsZip64())
fileEntry.setZip64Data();
std::string header = fileEntry.createHeader();
ostr.write(header.c_str(), static_cast<std::streamsize>(header.size()));
}
}
ZipStreamBuf::~ZipStreamBuf()
{
// make sure destruction of streams happens in correct order
_ptrOBuf = 0;
_ptrOHelper = 0;
_ptrBuf = 0;
_ptrHelper = 0;
}
int ZipStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
if (!_ptrBuf) return 0; // directory entry
_ptrBuf->read(buffer, length);
int cnt = static_cast<int>(_ptrBuf->gcount());
if (cnt > 0)
{
_crc32.update(buffer, cnt);
}
else
{
if (_crc32.checksum() != _expectedCrc32)
{
if (_checkCRC)
throw ZipException("CRC failure");
else
{
// the CRC value is written directly after the data block
// parse it directly from the input stream
ZipDataInfo nfo(*_pIstr, false);
// now push back the header to the stream, so that the ZipLocalFileHeader can read it
Poco::Int32 size = static_cast<Poco::Int32>(nfo.getFullHeaderSize());
_expectedCrc32 = nfo.getCRC32();
_pIstr->seekg(-size, std::ios::cur);
if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream");
if (!crcValid())
throw ZipException("CRC failure");
}
}
}
return cnt;
}
int ZipStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
{
if (!_ptrOBuf) return 0; // directory entry
if (length == 0)
return 0;
_bytesWritten += length;
_ptrOBuf->write(buffer, length);
_crc32.update(buffer, static_cast<unsigned int>(length));
return static_cast<int>(length);
}
void ZipStreamBuf::close(Poco::UInt64& extraDataSize)
{
extraDataSize = 0;
if (_ptrOBuf && _pHeader)
{
_ptrOBuf->flush();
DeflatingOutputStream* pDO = dynamic_cast<DeflatingOutputStream*>(_ptrOBuf.get());
if (pDO)
pDO->close();
if (_ptrOHelper)
{
_ptrOHelper->flush();
_ptrOHelper->close();
}
_ptrOBuf = 0;
if (!*_pOstr) throw Poco::IOException("Bad output stream");
// write an extra datablock if required
// or fix the crc entries
poco_check_ptr(_pHeader);
_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())
{
if (_pHeader->needsZip64())
{
ZipDataInfo64 info;
info.setCRC32(_crc32.checksum());
info.setUncompressedSize(_bytesWritten);
info.setCompressedSize(_ptrOHelper->bytesWritten());
extraDataSize = info.getFullHeaderSize();
_pOstr->write(info.getRawHeader(), static_cast<std::streamsize>(extraDataSize));
}
else
{
ZipDataInfo info;
info.setCRC32(_crc32.checksum());
info.setUncompressedSize(static_cast<Poco::UInt32>(_bytesWritten));
info.setCompressedSize(static_cast<Poco::UInt32>(_ptrOHelper->bytesWritten()));
extraDataSize = info.getFullHeaderSize();
_pOstr->write(info.getRawHeader(), static_cast<std::streamsize>(extraDataSize));
}
}
else
{
_pOstr->seekp(_pHeader->getStartPos(), std::ios_base::beg);
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);
if (!*_pOstr) throw Poco::IOException("Bad output stream");
}
_pHeader = 0;
}
}
bool ZipStreamBuf::crcValid() const
{
if (!_ptrBuf) return true; // directory entry
return _crc32.checksum() == _expectedCrc32;
}
ZipIOS::ZipIOS(std::istream& istr, const ZipLocalFileHeader& fileEntry, bool reposition): _buf(istr, fileEntry, reposition)
{
poco_ios_init(&_buf);
}
ZipIOS::ZipIOS(std::ostream& ostr, ZipLocalFileHeader& fileEntry, bool reposition): _buf(ostr, fileEntry, reposition)
{
poco_ios_init(&_buf);
}
ZipIOS::~ZipIOS()
{
}
ZipStreamBuf* ZipIOS::rdbuf()
{
return &_buf;
}
ZipInputStream::ZipInputStream(std::istream& istr, const ZipLocalFileHeader& fileEntry, bool reposition): ZipIOS(istr, fileEntry, reposition), std::istream(&_buf)
{
if (!fileEntry.hasSupportedCompressionMethod())
{
throw ZipException(Poco::format("Unsupported compression method (%d)", static_cast<int>(fileEntry.getCompressionMethod())), fileEntry.getFileName());
}
}
ZipInputStream::~ZipInputStream()
{
}
bool ZipInputStream::crcValid() const
{
return _buf.crcValid();
}
ZipOutputStream::ZipOutputStream(std::ostream& ostr, ZipLocalFileHeader& fileEntry, bool seekableOutput): ZipIOS(ostr, fileEntry, seekableOutput), std::ostream(&_buf)
{
}
ZipOutputStream::~ZipOutputStream()
{
}
void ZipOutputStream::close(Poco::UInt64& extraDataSize)
{
flush();
_buf.close(extraDataSize);
}
} } // namespace Poco::Zip

249
vendor/POCO/Zip/src/ZipUtil.cpp vendored Normal file
View File

@@ -0,0 +1,249 @@
//
// ZipUtil.cpp
//
// Library: Zip
// Package: Zip
// Module: ZipUtil
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Zip/ZipUtil.h"
#include "Poco/Zip/ZipException.h"
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipFileInfo.h"
#include "Poco/Zip/ZipDataInfo.h"
#include "Poco/Zip/ZipArchiveInfo.h"
#include <cstring>
namespace Poco {
namespace Zip {
Poco::DateTime ZipUtil::parseDateTime(const char* pVal, const Poco::UInt32 timePos, const Poco::UInt32 datePos)
{
Poco::UInt16 time = ZipUtil::get16BitValue(pVal, timePos);
Poco::UInt16 date = ZipUtil::get16BitValue(pVal, datePos);
// TIME: second 0-4, minute 5-10, hour 11-15, second resolution is 2!
int sec = 2*(time & 0x001fu); // 0000 0000 0001 1111
int min = ((time & 0x07e0u) >> 5); // 0000 0111 1110 0000
int hour = ((time & 0xf800u) >> 11); // 1111 1000 0000 0000
// DATE: day 0-4, month 5-8, year (starting with 1980): 9-16
int day = (date & 0x001fu); // 0000 0000 0001 1111
int mon = ((date & 0x01e0u) >> 5); // 0000 0001 1110 0000
int year = 1980+((date & 0xfe00u) >> 9); // 1111 1110 0000 0000
if (Poco::DateTime::isValid(year, mon, day, hour, min, sec))
return Poco::DateTime(year, mon, day, hour, min, sec);
else
return Poco::DateTime(1970, 01, 01);
}
void ZipUtil::setDateTime(const Poco::DateTime& dt, char* pVal, const Poco::UInt32 timePos, const Poco::UInt32 datePos)
{
// TIME: second 0-4, minute 5-10, hour 11-15
Poco::UInt16 time = static_cast<Poco::UInt16>((dt.second()/2) + (dt.minute()<<5) + (dt.hour()<<11));
// DATE: day 0-4, month 5-8, year (starting with 1980): 9-16
int year = dt.year() - 1980;
if (year < 0) year = 0;
Poco::UInt16 date = static_cast<Poco::UInt16>(dt.day() + (dt.month()<<5) + (year<<9));
ZipUtil::set16BitValue(time, pVal, timePos);
ZipUtil::set16BitValue(date, pVal, datePos);
}
std::string ZipUtil::fakeZLibInitString(ZipCommon::CompressionLevel cl)
{
std::string init(2, ' ');
// compression info:
// deflate is used, bit 0-3: 0x08
// dictionary size is always 32k: calc ld2(32k)-8 = ld2(2^15) - 8 = 15 - 8 = 7 --> bit 4-7: 0x70
init[0] = '\x78';
// now fake flags
// bits 0-4 check bits: set them so that init[0]*256+init[1] % 31 == 0
// bit 5: preset dictionary? always no for us, set to 0
// bits 6-7: compression level: 00 very fast, 01 fast, 10 normal, 11 best
if (cl == ZipCommon::CL_SUPERFAST)
init[1] = '\x00';
else if (cl == ZipCommon::CL_FAST)
init[1] = '\x40';
else if (cl == ZipCommon::CL_NORMAL)
init[1] = '\x80';
else
init[1] = '\xc0';
// now set the last 5 bits
Poco::UInt16 tmpVal = ((Poco::UInt16)init[0])*256+((unsigned char)init[1]);
char checkBits = (31 - (char)(tmpVal%31));
init[1] |= checkBits; // set the lower 5 bits
tmpVal = ((Poco::UInt16)init[0])*256+((unsigned char)init[1]);
poco_assert_dbg ((tmpVal % 31) == 0);
return init;
}
void ZipUtil::sync(std::istream& in)
{
enum
{
PREFIX = 2,
BUFFER_SIZE = 1024
};
char temp[BUFFER_SIZE];
in.read(temp, PREFIX);
std::size_t tempPos = PREFIX;
while (in.good() && !in.eof())
{
// all zip headers start withe same 2byte prefix
if (std::memcmp(ZipLocalFileHeader::HEADER, &temp[tempPos - PREFIX], PREFIX) == 0)
{
// we have a possible header!
// read the next 2 bytes
in.read(temp+tempPos, PREFIX);
tempPos += PREFIX;
if (std::memcmp(ZipLocalFileHeader::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0 ||
std::memcmp(ZipArchiveInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0 ||
std::memcmp(ZipFileInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0 ||
std::memcmp(ZipDataInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0)
{
if (std::memcmp(ZipLocalFileHeader::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 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.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.seekg(-4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
else
{
in.seekg(-4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
return;
}
else
{
// 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;
}
}
else
{
// read one byte
in.read(temp + tempPos, 1);
++tempPos;
}
if (tempPos > (BUFFER_SIZE - ZipCommon::HEADER_SIZE))
{
std::memcpy(temp, &temp[tempPos - ZipCommon::HEADER_SIZE], ZipCommon::HEADER_SIZE);
tempPos = ZipCommon::HEADER_SIZE;
}
}
}
void ZipUtil::syncDataDescriptor(std::istream & in, bool force64)
{
std::streampos start = in.tellg();
const int eof = std::char_traits<char>::eof();
int c = in.get();
do
{
while (c != eof && c != ZipDataInfo::HEADER[0]) { c = in.get(); }
if (c == eof) return;
bool match = true;
for (int i = 1; i < 4 && match; i++)
{
c = in.get();
if (c != ZipDataInfo::HEADER[i]) match = false;
}
if (match)
{
std::streampos end = in.tellg();
if (force64)
{
ZipDataInfo64 nfo(in, true);
if (nfo.isValid())
{
if (end - start == nfo.getCompressedSize() + 4)
{
in.seekg(-static_cast<int>(ZipDataInfo64::getFullHeaderSize()), std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
break;
}
else
{
in.seekg(-static_cast<int>(ZipDataInfo64::getFullHeaderSize()) + 4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
}
}
else
{
ZipDataInfo nfo(in, true);
if (nfo.isValid())
{
if (end - start == nfo.getCompressedSize() + 4)
{
in.seekg(-static_cast<int>(ZipDataInfo::getFullHeaderSize()), std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
break;
}
else
{
in.seekg(-static_cast<int>(ZipDataInfo::getFullHeaderSize()) + 4, std::ios::cur);
if (!in.good()) throw Poco::IOException("Failed to seek on input stream");
}
}
}
}
} while (c != eof);
}
void ZipUtil::verifyZipEntryFileName(const std::string& fn)
{
if (fn.find("\\") != std::string::npos)
throw ZipException("Illegal entry name " + fn + " containing \\");
if (fn == "/")
throw ZipException("Illegal entry name /");
if (fn.empty())
throw ZipException("Illegal empty entry name");
if (!ZipCommon::isValidPath(fn))
throw ZipException("Illegal entry name " + fn + " containing parent directory reference");
}
std::string ZipUtil::validZipEntryFileName(const Poco::Path& entry)
{
std::string fn = entry.toString(Poco::Path::PATH_UNIX);
verifyZipEntryFileName(fn);
return fn;
}
} } // namespace Poco::Zip