1 // SPDX-License-Identifier: 0BSD 2 3 /////////////////////////////////////////////////////////////////////////////// 4 // 5 /// \file fuzz_common.h 6 /// \brief Common macros and functions needed by the fuzz targets 7 // 8 // Authors: Maksym Vatsyk 9 // Lasse Collin 10 // 11 /////////////////////////////////////////////////////////////////////////////// 12 13 #include <inttypes.h> 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include "lzma.h" 17 18 // Some header values can make liblzma allocate a lot of RAM 19 // (up to about 4 GiB with liblzma 5.2.x). We set a limit here to 20 // prevent extreme allocations when fuzzing. 21 #define MEM_LIMIT (300 << 20) // 300 MiB 22 23 // Amount of input to pass to lzma_code() per call at most. 24 #define IN_CHUNK_SIZE 2047 25 26 27 static void 28 fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) { 29 // Output buffer for decompressed data. This is write only; nothing 30 // cares about the actual data written here. 31 uint8_t outbuf[4096]; 32 33 // Pass half of the input on the first call and then proceed in 34 // chunks. It's fine that this rounds to 0 when inbuf_size is 1. 35 stream->next_in = inbuf; 36 stream->avail_in = inbuf_size / 2; 37 38 lzma_action action = LZMA_RUN; 39 40 lzma_ret ret; 41 do { 42 if (stream->avail_in == 0 && inbuf_size > 0) { 43 const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE 44 ? inbuf_size : IN_CHUNK_SIZE; 45 46 stream->next_in = inbuf; 47 stream->avail_in = chunk_size; 48 49 inbuf += chunk_size; 50 inbuf_size -= chunk_size; 51 52 if (inbuf_size == 0) 53 action = LZMA_FINISH; 54 } 55 56 if (stream->avail_out == 0) { 57 // outbuf became full. We don't care about the 58 // uncompressed data there, so we simply reuse 59 // the outbuf and overwrite the old data. 60 stream->next_out = outbuf; 61 stream->avail_out = sizeof(outbuf); 62 } 63 } while ((ret = lzma_code(stream, action)) == LZMA_OK); 64 65 // LZMA_PROG_ERROR should never happen as long as the code calling 66 // the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign 67 // of a bug in either this function or in liblzma. 68 if (ret == LZMA_PROG_ERROR) { 69 fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n"); 70 abort(); 71 } 72 } 73