1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Fuzz test program for liblzma
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
19 // Output buffer for decompressed data. This is write only; nothing cares
20 // about the actual data written here.
21 static uint8_t outbuf
[4096];
25 LLVMFuzzerTestOneInput(const uint8_t *inbuf
, size_t inbuf_size
)
27 // Some header values can make liblzma allocate a lot of RAM
28 // (up to about 4 GiB with liblzma 5.2.x). We set a limit here to
29 // prevent extreme allocations when fuzzing.
30 const uint64_t memlimit
= 300 << 20; // 300 MiB
32 // Initialize a .xz decoder using the above memory usage limit.
33 // Enable support for concatenated .xz files which is used when
34 // decompressing regular .xz files (instead of data embedded inside
35 // some other file format). Integrity checks on the uncompressed
36 // data are ignored to make fuzzing more effective (incorrect check
37 // values won't prevent the decoder from processing more input).
39 // The flag LZMA_IGNORE_CHECK doesn't disable verification of header
40 // CRC32 values. Those checks are disabled when liblzma is built
41 // with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
42 lzma_stream strm
= LZMA_STREAM_INIT
;
43 lzma_ret ret
= lzma_stream_decoder(&strm
, memlimit
,
44 LZMA_CONCATENATED
| LZMA_IGNORE_CHECK
);
46 // This should never happen unless the system has
47 // no free memory or address space to allow the small
48 // allocations that the initialization requires.
49 fprintf(stderr
, "lzma_stream_decoder() failed (%d)\n", ret
);
53 // Give the whole input buffer at once to liblzma.
54 // Output buffer isn't initialized as liblzma only writes to it.
56 strm
.avail_in
= inbuf_size
;
57 strm
.next_out
= outbuf
;
58 strm
.avail_out
= sizeof(outbuf
);
60 while ((ret
= lzma_code(&strm
, LZMA_FINISH
)) == LZMA_OK
) {
61 if (strm
.avail_out
== 0) {
62 // outbuf became full. We don't care about the
63 // uncompressed data there, so we simply reuse
64 // the outbuf and overwrite the old data.
65 strm
.next_out
= outbuf
;
66 strm
.avail_out
= sizeof(outbuf
);
70 // LZMA_PROG_ERROR should never happen as long as the code calling
71 // the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign
72 // of a bug in either this function or in liblzma.
73 if (ret
== LZMA_PROG_ERROR
) {
74 fprintf(stderr
, "lzma_code() returned LZMA_PROG_ERROR\n");
78 // Free the allocated memory.