summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2023-12-21 00:17:54 +0000
committerCopybara-Service <copybara-worker@google.com>2023-12-20 16:27:08 -0800
commit40e35a76af71511ee701001df5bc1ba216472d67 (patch)
tree1f1461ade2b3ae700aa9893e05944420d172b4b1
parent002f75df25f7d42aa7c4f4b63fc21b25f71ae26f (diff)
downloadzlib-40e35a76af71511ee701001df5bc1ba216472d67.tar.gz
deflateCopy(): Fix allocation and copying of pending_buf in LIT_MEM mode
This applies the fix from https://github.com/madler/zlib/pull/900 and adds a test. Bug: 1513368 Change-Id: I38025c66e1ef2420c726406ddefe6c728bdb6458 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5139141 Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org> Auto-Submit: Hans Wennborg <hans@chromium.org> Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org> Cr-Commit-Position: refs/heads/main@{#1239920} NOKEYCHECK=True GitOrigin-RevId: 5672e5e75c159ba1742f8cfd784d294cff21c597
-rw-r--r--contrib/tests/utils_unittest.cc55
-rw-r--r--deflate.c8
2 files changed, 63 insertions, 0 deletions
diff --git a/contrib/tests/utils_unittest.cc b/contrib/tests/utils_unittest.cc
index d06dbc9..4a80277 100644
--- a/contrib/tests/utils_unittest.cc
+++ b/contrib/tests/utils_unittest.cc
@@ -1025,6 +1025,61 @@ TEST(ZlibTest, DeflateZFixedCorruption) {
0);
}
+TEST(ZlibTest, DeflateCopy) {
+ // Check that deflateCopy() works.
+
+ z_stream stream1;
+ stream1.zalloc = Z_NULL;
+ stream1.zfree = Z_NULL;
+ int ret =
+ deflateInit(&stream1, Z_DEFAULT_COMPRESSION);
+ ASSERT_EQ(ret, Z_OK);
+ std::vector<uint8_t> compressed(
+ deflateBound(&stream1, strlen(zFixedCorruptionData)));
+ stream1.next_out = compressed.data();
+ stream1.avail_out = compressed.size();
+
+ // Compress the first 1000 bytes.
+ stream1.next_in = (uint8_t*)zFixedCorruptionData;
+ stream1.avail_in = 1000;
+ ret = deflate(&stream1, Z_NO_FLUSH);
+ ASSERT_EQ(ret, Z_OK);
+
+ // Copy the stream state.
+ z_stream stream2;
+ ret = deflateCopy(&stream2, &stream1);
+ ASSERT_EQ(ret, Z_OK);
+ deflateEnd(&stream1);
+
+ // Compress the remaining bytes.
+ stream2.next_in = (uint8_t*)zFixedCorruptionData + (1000 - stream2.avail_in);
+ stream2.avail_in = strlen(zFixedCorruptionData) - (1000 - stream2.avail_in);
+ ret = deflate(&stream2, Z_FINISH);
+ ASSERT_EQ(ret, Z_STREAM_END);
+ size_t compressed_sz = compressed.size() - stream2.avail_out;
+ deflateEnd(&stream2);
+
+ // Check that decompression is successful.
+ std::vector<uint8_t> decompressed(strlen(zFixedCorruptionData));
+ z_stream stream;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ ret = inflateInit(&stream);
+ ASSERT_EQ(ret, Z_OK);
+ stream.next_in = compressed.data();
+ stream.avail_in = compressed_sz;
+ stream.next_out = decompressed.data();
+ stream.avail_out = decompressed.size();
+ ret = inflate(&stream, Z_FINISH);
+ ASSERT_EQ(ret, Z_STREAM_END);
+ inflateEnd(&stream);
+
+ EXPECT_EQ(decompressed.size(), strlen(zFixedCorruptionData));
+ EXPECT_EQ(
+ memcmp(zFixedCorruptionData, decompressed.data(), decompressed.size()),
+ 0);
+}
+
// TODO(gustavoa): make these tests run standalone.
#ifndef CMAKE_STANDALONE_UNITTESTS
diff --git a/deflate.c b/deflate.c
index adb2488..4920e70 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1345,7 +1345,11 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+#ifdef LIT_MEM
+ ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 5);
+#else
ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
+#endif
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
ds->pending_buf == Z_NULL) {
@@ -1356,7 +1360,11 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+#ifdef LIT_MEM
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->lit_bufsize * 5);
+#else
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+#endif
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
#ifdef LIT_MEM