poco
poco copied to clipboard
Poco::Zip::Compress::addFile with Poco::MemoryInputStream broken since 1.12.0 for at least some use-cases
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);
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 .
This issue is stale because it has been open for 365 days with no activity.
@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.