diff options
author | Hans Wennborg <hans@chromium.org> | 2024-02-29 21:26:20 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-02-29 13:36:24 -0800 |
commit | c74625d62c5132353131496c0ec68ec633e9c71b (patch) | |
tree | 358ad1843e3d127291fb3482a0c5ad695b42b8c6 | |
parent | 3787595bbbd3a374613713164db935e8331f5825 (diff) | |
download | zlib-c74625d62c5132353131496c0ec68ec633e9c71b.tar.gz |
[zlib] Fix deflateBound() with chromium_zlib_hash and non-default memLevel
When chromium_zlib_hash is enabled, we set hash_bits to 15 regardless
of memLevel, throwing off the computations in deflateBound(). Return
a conservative bound instead for now.
Bug: 40270738
Change-Id: I9fbe64887ff9520e22d1be5d0557548ec2e7db45
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5335167
Auto-Submit: Hans Wennborg <hans@chromium.org>
Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org>
Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1267210}
NOKEYCHECK=True
GitOrigin-RevId: bd787538b3dc5dcd9243d4ef0a524fdf07cd87b0
-rw-r--r-- | contrib/tests/utils_unittest.cc | 40 | ||||
-rw-r--r-- | deflate.c | 6 |
2 files changed, 46 insertions, 0 deletions
diff --git a/contrib/tests/utils_unittest.cc b/contrib/tests/utils_unittest.cc index 3d6672d..0cc1081 100644 --- a/contrib/tests/utils_unittest.cc +++ b/contrib/tests/utils_unittest.cc @@ -1105,6 +1105,46 @@ TEST(ZlibTest, GzipStored) { deflateEnd(&stream); } +TEST(ZlibTest, DeflateBound) { + // Check that the deflateBound() isn't too low when using non-default + // parameters (crbug.com/40270738). + const int level = 9; + const int windowBits = 15; + const int memLevel = 1; + const int strategy = Z_FIXED; + const uint8_t src[] = { + 49, 255, 255, 20, 45, 49, 167, 56, 55, 255, 255, 255, 223, 255, 49, + 255, 3, 78, 0, 0, 141, 253, 209, 163, 29, 195, 43, 60, 199, 123, + 112, 35, 134, 13, 148, 102, 212, 4, 184, 103, 7, 102, 225, 102, 156, + 164, 78, 48, 70, 49, 125, 162, 55, 116, 161, 174, 83, 0, 59, 0, + 225, 140, 0, 0, 63, 63, 4, 15, 198, 30, 126, 196, 33, 99, 135, + 41, 192, 82, 28, 105, 216, 170, 221, 14, 61, 1, 0, 0, 22, 195, + 45, 53, 244, 163, 167, 158, 229, 68, 18, 112, 49, 174, 43, 75, 90, + 161, 85, 19, 36, 163, 118, 228, 169, 180, 161, 237, 234, 253, 197, 234, + 66, 106, 12, 42, 124, 96, 160, 144, 183, 194, 157, 167, 202, 217}; + + z_stream stream; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + int ret = + deflateInit2(&stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + ASSERT_EQ(ret, Z_OK); + size_t deflate_bound = deflateBound(&stream, sizeof(src)); + + uint8_t out[sizeof(src) * 10]; + stream.next_in = (uint8_t*)src; + stream.avail_in = sizeof(src); + stream.next_out = out; + stream.avail_out = sizeof(out); + ret = deflate(&stream, Z_FINISH); + ASSERT_EQ(ret, Z_STREAM_END); + + size_t out_size = sizeof(out) - stream.avail_out; + EXPECT_LE(out_size, deflate_bound); + + deflateEnd(&stream); +} + // TODO(gustavoa): make these tests run standalone. #ifndef CMAKE_STANDALONE_UNITTESTS @@ -923,6 +923,12 @@ uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { wraplen = 6; } + /* With Chromium's hashing, s->hash_bits may not correspond to the + memLevel, making the computations below incorrect. Return the + conservative bound. */ + if (s->chromium_zlib_hash) + return (fixedlen > storelen ? fixedlen : storelen) + wraplen; + /* if not default parameters, return one of the conservative bounds */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + |