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:
38
vendor/POCO/Zip/src/Add.cpp
vendored
Normal file
38
vendor/POCO/Zip/src/Add.cpp
vendored
Normal 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
229
vendor/POCO/Zip/src/AutoDetectStream.cpp
vendored
Normal 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
389
vendor/POCO/Zip/src/Compress.cpp
vendored
Normal 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
187
vendor/POCO/Zip/src/Decompress.cpp
vendored
Normal 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
34
vendor/POCO/Zip/src/Delete.cpp
vendored
Normal 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
37
vendor/POCO/Zip/src/Keep.cpp
vendored
Normal 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
32
vendor/POCO/Zip/src/ParseCallback.cpp
vendored
Normal 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
255
vendor/POCO/Zip/src/PartialStream.cpp
vendored
Normal 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
36
vendor/POCO/Zip/src/Rename.cpp
vendored
Normal 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
37
vendor/POCO/Zip/src/Replace.cpp
vendored
Normal 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
46
vendor/POCO/Zip/src/SkipCallback.cpp
vendored
Normal 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
144
vendor/POCO/Zip/src/ZipArchive.cpp
vendored
Normal 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
190
vendor/POCO/Zip/src/ZipArchiveInfo.cpp
vendored
Normal 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
56
vendor/POCO/Zip/src/ZipCommon.cpp
vendored
Normal 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
106
vendor/POCO/Zip/src/ZipDataInfo.cpp
vendored
Normal 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
27
vendor/POCO/Zip/src/ZipException.cpp
vendored
Normal 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
188
vendor/POCO/Zip/src/ZipFileInfo.cpp
vendored
Normal 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
|
262
vendor/POCO/Zip/src/ZipLocalFileHeader.cpp
vendored
Normal file
262
vendor/POCO/Zip/src/ZipLocalFileHeader.cpp
vendored
Normal 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
171
vendor/POCO/Zip/src/ZipManipulator.cpp
vendored
Normal 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
32
vendor/POCO/Zip/src/ZipOperation.cpp
vendored
Normal 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
337
vendor/POCO/Zip/src/ZipStream.cpp
vendored
Normal 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
249
vendor/POCO/Zip/src/ZipUtil.cpp
vendored
Normal 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
|
Reference in New Issue
Block a user