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 (std::memcmp(header, ZipDataInfo64::HEADER, sizeof(header)) == 0) { 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! }
void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead) { if (!assumeHeaderRead) { inp.read(_rawHeader, ZipCommon::HEADER_SIZE); } else { std::memcpy(_rawHeader, HEADER, ZipCommon::HEADER_SIZE); } poco_assert (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) == 0); // 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() <= 2); poco_assert (ZipUtil::get16BitValue(_rawHeader, COMPR_METHOD_POS) < ZipCommon::CM_UNUSED); parseDateTime(); Poco::UInt16 len = getFileNameLength(); Poco::Buffer<char> buf(len); inp.read(buf.begin(), len); _fileName = std::string(buf.begin(), len); if (hasExtraField()) { len = getExtraFieldLength(); Poco::Buffer<char> xtra(len); inp.read(xtra.begin(), len); _extraField = std::string(xtra.begin(), len); } if (!searchCRCAndSizesAfterData()) { _crc32 = getCRCFromHeader(); _compressedSize = getCompressedSizeFromHeader(); _uncompressedSize = getUncompressedSizeFromHeader(); } }
void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead) { if (!assumeHeaderRead) { inp.read(_rawHeader, ZipCommon::HEADER_SIZE); } else { std::memcpy(_rawHeader, HEADER, ZipCommon::HEADER_SIZE); } poco_assert (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) == 0); // 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(); 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(); 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) { poco_assert(size >= 8); if (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; } } } }