summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2024-02-22 07:01:51 +0000
committerCopybara-Service <copybara-worker@google.com>2024-02-21 23:08:18 -0800
commit74a1c5030338acadbbfb32609774a974be89007f (patch)
tree1b79a7bf87717df9198e092ce12d68f0cc9bf6a1
parent03c356e4c106e4e6850edaae29be45290a2cb36c (diff)
downloadzlib-74a1c5030338acadbbfb32609774a974be89007f.tar.gz
[zlib] Increase the coverage of deflate_fuzzer
- Use all the wrappers (gzip, zlib, none); not just the default (zlib) - Pass random sized input and output buffers - Disable the deflateBound() check for now This makes the fuzzer cover the bug below. Bug: 325990053, 40263542 Change-Id: I8ed571b7e84155d2fc0f4f929a5b24a4c9583958 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5310394 Commit-Queue: Hans Wennborg <hans@chromium.org> Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org> Cr-Commit-Position: refs/heads/main@{#1263816} NOKEYCHECK=True GitOrigin-RevId: 69575154e8a598d1f9347877caf34d71f08e081a
-rw-r--r--contrib/tests/fuzzers/deflate_fuzzer.cc73
1 files changed, 53 insertions, 20 deletions
diff --git a/contrib/tests/fuzzers/deflate_fuzzer.cc b/contrib/tests/fuzzers/deflate_fuzzer.cc
index 64892bc..6f3e45e 100644
--- a/contrib/tests/fuzzers/deflate_fuzzer.cc
+++ b/contrib/tests/fuzzers/deflate_fuzzer.cc
@@ -23,42 +23,75 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);
- int level = fdp.PickValueInArray({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+ int level = fdp.PickValueInArray({-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
int windowBits = fdp.PickValueInArray({9, 10, 11, 12, 13, 14, 15});
int memLevel = fdp.PickValueInArray({1, 2, 3, 4, 5, 6, 7, 8, 9});
int strategy = fdp.PickValueInArray(
{Z_DEFAULT_STRATEGY, Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED});
- std::vector<uint8_t> src = fdp.ConsumeRemainingBytes<uint8_t>();
+
+ if (fdp.ConsumeBool()) {
+ // Gzip wrapper.
+ windowBits += 16;
+ } else if (fdp.ConsumeBool()) {
+ // Raw deflate.
+ windowBits *= -1;
+ } else {
+ // Default: zlib wrapper.
+ }
+
+ std::vector<uint8_t> src;
+ std::vector<uint8_t> compressed;
+ static const int kMinChunk = 1;
+ static const int kMaxChunk = 512 * 1024;
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
-
- // Compress the data one byte at a time to exercise the streaming code.
int ret =
deflateInit2(&stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
ASSERT(ret == Z_OK);
- size_t deflate_bound = deflateBound(&stream, src.size());
-
- std::vector<uint8_t> compressed(src.size() * 2 + 1000);
- stream.next_out = compressed.data();
- stream.avail_out = compressed.size();
- for (uint8_t b : src) {
- stream.next_in = &b;
- stream.avail_in = 1;
+ // Stream with random-sized input and output buffers.
+ while (fdp.ConsumeBool()) {
+ std::vector<uint8_t> src_chunk = fdp.ConsumeBytes<uint8_t>(
+ fdp.ConsumeIntegralInRange(kMinChunk, kMaxChunk));
+ std::vector<uint8_t> out_chunk(
+ fdp.ConsumeIntegralInRange(kMinChunk, kMaxChunk));
+ stream.next_in = src_chunk.data();
+ stream.avail_in = src_chunk.size();
+ stream.next_out = out_chunk.data();
+ stream.avail_out = out_chunk.size();
ret = deflate(&stream, Z_NO_FLUSH);
- ASSERT(ret == Z_OK);
+ ASSERT(ret == Z_OK || ret == Z_BUF_ERROR);
+
+ src.insert(src.end(), src_chunk.begin(), src_chunk.end() - stream.avail_in);
+ compressed.insert(compressed.end(), out_chunk.begin(),
+ out_chunk.end() - stream.avail_out);
+ }
+ // Finish up.
+ while (true) {
+ std::vector<uint8_t> out_chunk(
+ fdp.ConsumeIntegralInRange(kMinChunk, kMaxChunk));
+ stream.next_in = Z_NULL;
+ stream.avail_in = 0;
+ stream.next_out = out_chunk.data();
+ stream.avail_out = out_chunk.size();
+ ret = deflate(&stream, Z_FINISH);
+ compressed.insert(compressed.end(), out_chunk.begin(),
+ out_chunk.end() - stream.avail_out);
+ if (ret == Z_STREAM_END) {
+ break;
+ }
+ ASSERT(ret == Z_OK || Z_BUF_ERROR);
}
- stream.next_in = Z_NULL;
- stream.avail_in = 0;
- ret = deflate(&stream, Z_FINISH);
- ASSERT(ret == Z_STREAM_END);
- compressed.resize(compressed.size() - stream.avail_out);
- deflateEnd(&stream);
// Check that the bound was correct.
- ASSERT(compressed.size() <= deflate_bound);
+ // size_t deflate_bound = deflateBound(&stream, src.size());
+ // TODO(crbug.com/40270738): This does not always hold.
+ // ASSERT(compressed.size() <= deflate_bound);
+
+ deflateEnd(&stream);
+
// Verify that the data decompresses correctly.
ret = inflateInit2(&stream, windowBits);