poco icon indicating copy to clipboard operation
poco copied to clipboard

Poco::Zip::Compress::addFile with Poco::MemoryInputStream broken since 1.12.0 for at least some use-cases

Open insi-eb opened this issue 2 years ago • 4 comments

Describe the bug

When trying to add a small file to a zip archive from a Poco::MemoryInputStream via Compress::addFile(), not all bytes are added/compressed.

To Reproduce

run the following minimal test case with Poco 1.12.0 or 1.12.1:

{
    constexpr Poco::UInt64 const size = 4;
    char const data[size] = {0x01, 0x02, 0x03, 0x04};
    Poco::MemoryInputStream stream(data, size);
    std::string const memStreamFileName = "memStream";

    Poco::FileOutputStream out(Poco::Path::temp() + "memStream.zip", std::ios::trunc);
    Compress zip(out, true);
    zip.addFile(stream, Poco::DateTime(0.0), memStreamFileName);
    ZipArchive a(zip.close());
    ZipArchive::FileHeaders::const_iterator it = a.findHeader(memStreamFileName);
    assertTrue (it != a.headerEnd());
    ZipLocalFileHeader const& file = it->second;
    assertTrue (file.getUncompressedSize() == size);
}

only one byte instead of 4 bytes ends up in the output archive and the last assertion fails

Expected behavior

all 4 bytes are added to the file in the output archive and are compressed

Logs n/a

Screenshots n/a

Please add relevant environment information:

  • OS Type and Version: Linux w/ 5.14 kernel, clang-14.0.6 w/ libstdc++-11
  • POCO Version: 1.12.[0,1]
  • Third-party product (eg. database or library) type and version: n/a

Additional context

The following patch fixes this (first change is for consistency reasons):

diff -ru a/Zip/src/Compress.cpp b/Zip/src/Compress.cpp
--- a/Zip/src/Compress.cpp
+++ b/Zip/src/Compress.cpp
@@ -84,9 +84,9 @@
 	std::streamoff localHeaderOffset = _offset;
 	ZipLocalFileHeader hdr(fileName, lastModifiedAt, cm, cl, _forceZip64);
 	std::streampos pos = in.tellg();
-	in.seekg(0, in.end);
+	in.seekg(0, std::ios::end);
 	std::streampos length = in.tellg();
-	in.seekg(pos);
+	in.seekg(pos, std::ios::beg);
 	if (length >= ZipCommon::ZIP64_MAGIC)
 		hdr.setZip64Data();
 	hdr.setStartPos(localHeaderOffset);

insi-eb avatar Jul 18 '22 11:07 insi-eb

It is PR #3604 that breaks Poco::Zip.

The suggested patch does not solve the case where the in stream is a Poco::Zip::ZipInputStream .

jbulow avatar Aug 29 '22 08:08 jbulow

This issue is stale because it has been open for 365 days with no activity.

github-actions[bot] avatar Aug 30 '23 02:08 github-actions[bot]

@jbulow @obiltschnig: is the case where the in stream is a Poco::Zip::ZipInputStream working on Poco 1.12.x branches? If not and this patch doesn't break another use-case, I'd ask you to add both the patch and the minimal test case to Poco 1.12.5 until someone volunteers to create a more comprehensive fix that also covers Poco::Zip::ZipInputStream.

At least right now there is at least one case broken that this patch does fix, and as long as this patch doesn't break currently working use-cases (which at least I couldn't see from the existing Poco tests IIRC), it should be a net improvement.

insi-eb avatar Aug 30 '23 11:08 insi-eb