Esempio n. 1
0
bool SkipCallback::handleZipEntry(std::istream& zipStream, const ZipLocalFileHeader& hdr)
{
	if (!hdr.searchCRCAndSizesAfterData())
		zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur);
	else
		ZipUtil::sync(zipStream);
	return true;
}
Esempio n. 2
0
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, start);
        }
        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, start);
        }
        else
        {
            _ptrBuf = new PartialInputStream(istr, start, end, reposition);
        }
    }
    else throw Poco::NotImplementedException("Unsupported compression method");
}
Esempio n. 3
0
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!
        std::string header = fileEntry.createHeader();
        ostr.write(header.c_str(), static_cast<std::streamsize>(header.size()));
    }
}
Esempio n. 4
0
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 + " containing parent directory reference");
			Poco::Path dir(_outDir, dirName);
			dir.makeDirectory();
			Poco::File aFile(dir);
			aFile.createDirectories();
		}
		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 + " containing parent directory reference");

		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;
}