Commit d4217668 for xz
commit d4217668a79e6ca440e673115155559c81e89b84
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Sep 9 14:14:40 2026 +0300
Tests: Reinitialize decoders twice in fuzzers
diff --git a/tests/ossfuzz/fuzz_decode_alone.c b/tests/ossfuzz/fuzz_decode_alone.c
index e11aa6be..79f3c64f 100644
--- a/tests/ossfuzz/fuzz_decode_alone.c
+++ b/tests/ossfuzz/fuzz_decode_alone.c
@@ -21,20 +21,25 @@ extern int
LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
{
lzma_stream strm = LZMA_STREAM_INIT;
+ strm.next_in = inbuf;
+ strm.avail_in = inbuf_size;
- // Initialize a LZMA alone decoder using the memory usage limit
- // defined in fuzz_common.h
- lzma_ret ret = lzma_alone_decoder(&strm, MEM_LIMIT);
+ lzma_ret ret;
- if (ret != LZMA_OK) {
- // This should never happen unless the system has
- // no free memory or address space to allow the small
- // allocations that the initialization requires.
- fprintf(stderr, "lzma_alone_decoder() failed (%d)\n", ret);
- abort();
- }
+ for (int i = 0; i < 3; ++i) {
+ ret = lzma_alone_decoder(&strm, MEM_LIMIT);
+
+ if (ret != LZMA_OK) {
+ // This should never happen unless the system has
+ // no free memory or address space to allow the small
+ // allocations that the initialization requires.
+ fprintf(stderr, "lzma_alone_decoder() failed (%d)\n",
+ ret);
+ abort();
+ }
- fuzz_code(&strm, inbuf, inbuf_size);
+ fuzz_code(&strm, strm.next_in, strm.avail_in);
+ }
// Free the allocated memory.
lzma_end(&strm);
diff --git a/tests/ossfuzz/fuzz_decode_stream.c b/tests/ossfuzz/fuzz_decode_stream.c
index c5675056..550c4118 100644
--- a/tests/ossfuzz/fuzz_decode_stream.c
+++ b/tests/ossfuzz/fuzz_decode_stream.c
@@ -21,31 +21,43 @@ extern int
LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
{
lzma_stream strm = LZMA_STREAM_INIT;
+ strm.next_in = inbuf;
+ strm.avail_in = inbuf_size;
- // Initialize a .xz decoder using the memory usage limit
- // defined in fuzz_common.h
- //
- // Enable support for concatenated .xz files which is used when
- // decompressing regular .xz files (instead of data embedded inside
- // some other file format). Integrity checks on the uncompressed
- // data are ignored to make fuzzing more effective (incorrect check
- // values won't prevent the decoder from processing more input).
- //
- // The flag LZMA_IGNORE_CHECK doesn't disable verification of
- // header CRC32 values. Those checks are disabled when liblzma is
- // built with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
- lzma_ret ret = lzma_stream_decoder(&strm, MEM_LIMIT,
- LZMA_CONCATENATED | LZMA_IGNORE_CHECK);
-
- if (ret != LZMA_OK) {
- // This should never happen unless the system has
- // no free memory or address space to allow the small
- // allocations that the initialization requires.
- fprintf(stderr, "lzma_stream_decoder() failed (%d)\n", ret);
- abort();
- }
+ lzma_ret ret;
+
+ for (int i = 0; i < 3; ++i) {
+ // Initialize a .xz decoder using the memory usage limit
+ // defined in fuzz_common.h
+ //
+ // After the first two iterations, enable support for
+ // concatenated .xz files which is used when decompressing
+ // regular .xz files (instead of data embedded inside some
+ // other file format). This way the first iteration won't
+ // consume all the input until the input is invalid.
+ //
+ // Integrity checks on the uncompressed data are ignored to
+ // make fuzzing more effective (incorrect check values won't
+ // prevent the decoder from processing more input).
+ //
+ // The flag LZMA_IGNORE_CHECK doesn't disable verification
+ // of header CRC32 values. Those checks are disabled when
+ // liblzma is built with the
+ // #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
+ ret = lzma_stream_decoder(&strm, MEM_LIMIT, LZMA_IGNORE_CHECK
+ | (i >= 2 ? LZMA_CONCATENATED : 0));
- fuzz_code(&strm, inbuf, inbuf_size);
+ if (ret != LZMA_OK) {
+ // This should never happen unless the system has
+ // no free memory or address space to allow the small
+ // allocations that the initialization requires.
+ fprintf(stderr, "lzma_stream_decoder() failed (%d)\n",
+ ret);
+ abort();
+ }
+
+ fuzz_code(&strm, inbuf, inbuf_size);
+ }
// Free the allocated memory.
lzma_end(&strm);
diff --git a/tests/ossfuzz/fuzz_decode_stream_mt.c b/tests/ossfuzz/fuzz_decode_stream_mt.c
index 23ea9765..6beb68c5 100644
--- a/tests/ossfuzz/fuzz_decode_stream_mt.c
+++ b/tests/ossfuzz/fuzz_decode_stream_mt.c
@@ -20,26 +20,36 @@ extern int
LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
{
lzma_stream strm = LZMA_STREAM_INIT;
+ strm.next_in = inbuf;
+ strm.avail_in = inbuf_size;
lzma_mt mt = {
- .flags = LZMA_CONCATENATED | LZMA_IGNORE_CHECK,
+ .flags = /*LZMA_CONCATENATED |*/ LZMA_IGNORE_CHECK,
.threads = 2,
.timeout = 0,
.memlimit_threading = MEM_LIMIT / 2,
.memlimit_stop = MEM_LIMIT,
};
- lzma_ret ret = lzma_stream_decoder_mt(&strm, &mt);
+ lzma_ret ret;
- if (ret != LZMA_OK) {
- // This should never happen unless the system has
- // no free memory or address space to allow the small
- // allocations that the initialization requires.
- fprintf(stderr, "lzma_stream_decoder_mt() failed (%d)\n", ret);
- abort();
- }
+ for (int i = 0; i < 3; ++i) {
+ if (i == 2)
+ mt.flags |= LZMA_CONCATENATED;
+
+ ret = lzma_stream_decoder_mt(&strm, &mt);
- fuzz_code(&strm, inbuf, inbuf_size);
+ if (ret != LZMA_OK) {
+ // This should never happen unless the system has
+ // no free memory or address space to allow the small
+ // allocations that the initialization requires.
+ fprintf(stderr, "lzma_stream_decoder_mt() "
+ "failed (%d)\n", ret);
+ abort();
+ }
+
+ fuzz_code(&strm, strm.next_in, strm.avail_in);
+ }
lzma_end(&strm);