diff options
author | Hans Wennborg <hans@chromium.org> | 2023-12-21 00:17:54 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-12-20 16:27:08 -0800 |
commit | 40e35a76af71511ee701001df5bc1ba216472d67 (patch) | |
tree | 1f1461ade2b3ae700aa9893e05944420d172b4b1 | |
parent | 002f75df25f7d42aa7c4f4b63fc21b25f71ae26f (diff) | |
download | zlib-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.cc | 55 | ||||
-rw-r--r-- | deflate.c | 8 |
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 @@ -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 |