summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2024-02-29 21:26:20 +0000
committerCopybara-Service <copybara-worker@google.com>2024-02-29 13:36:24 -0800
commitc74625d62c5132353131496c0ec68ec633e9c71b (patch)
tree358ad1843e3d127291fb3482a0c5ad695b42b8c6
parent3787595bbbd3a374613713164db935e8331f5825 (diff)
downloadzlib-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.cc40
-rw-r--r--deflate.c6
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
diff --git a/deflate.c b/deflate.c
index 4920e70..4371158 100644
--- a/deflate.c
+++ b/deflate.c
@@ -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) +