Coverage Report

Created: 2026-04-12 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xz/tests/ossfuzz/fuzz_common.h
Line
Count
Source
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
56.0k
#define MEM_LIMIT (300 << 20) // 300 MiB
22
23
// Amount of input to pass to lzma_code() per call at most.
24
76.0k
#define IN_CHUNK_SIZE 2047
25
26
27
static void
28
18.1k
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
18.1k
  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
18.1k
  stream->next_in = inbuf;
36
18.1k
  stream->avail_in = inbuf_size / 2;
37
38
18.1k
  lzma_action action = LZMA_RUN;
39
40
18.1k
  lzma_ret ret;
41
390k
  do {
42
390k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
46.7k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
46.7k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
46.7k
      stream->next_in = inbuf;
47
46.7k
      stream->avail_in = chunk_size;
48
49
46.7k
      inbuf += chunk_size;
50
46.7k
      inbuf_size -= chunk_size;
51
52
46.7k
      if (inbuf_size == 0)
53
17.4k
        action = LZMA_FINISH;
54
46.7k
    }
55
56
390k
    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
334k
      stream->next_out = outbuf;
61
334k
      stream->avail_out = sizeof(outbuf);
62
334k
    }
63
390k
  } 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
18.1k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
18.1k
}
fuzz_decode_stream_mt.c:fuzz_code
Line
Count
Source
28
5.74k
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
5.74k
  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
5.74k
  stream->next_in = inbuf;
36
5.74k
  stream->avail_in = inbuf_size / 2;
37
38
5.74k
  lzma_action action = LZMA_RUN;
39
40
5.74k
  lzma_ret ret;
41
75.2k
  do {
42
75.2k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
20.4k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
20.4k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
20.4k
      stream->next_in = inbuf;
47
20.4k
      stream->avail_in = chunk_size;
48
49
20.4k
      inbuf += chunk_size;
50
20.4k
      inbuf_size -= chunk_size;
51
52
20.4k
      if (inbuf_size == 0)
53
5.45k
        action = LZMA_FINISH;
54
20.4k
    }
55
56
75.2k
    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
51.8k
      stream->next_out = outbuf;
61
51.8k
      stream->avail_out = sizeof(outbuf);
62
51.8k
    }
63
75.2k
  } 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
5.74k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.74k
}
fuzz_decode_stream.c:fuzz_code
Line
Count
Source
28
4.95k
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
4.95k
  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
4.95k
  stream->next_in = inbuf;
36
4.95k
  stream->avail_in = inbuf_size / 2;
37
38
4.95k
  lzma_action action = LZMA_RUN;
39
40
4.95k
  lzma_ret ret;
41
59.3k
  do {
42
59.3k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
18.5k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
18.5k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
18.5k
      stream->next_in = inbuf;
47
18.5k
      stream->avail_in = chunk_size;
48
49
18.5k
      inbuf += chunk_size;
50
18.5k
      inbuf_size -= chunk_size;
51
52
18.5k
      if (inbuf_size == 0)
53
4.60k
        action = LZMA_FINISH;
54
18.5k
    }
55
56
59.3k
    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
37.5k
      stream->next_out = outbuf;
61
37.5k
      stream->avail_out = sizeof(outbuf);
62
37.5k
    }
63
59.3k
  } 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
4.95k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
4.95k
}
fuzz_decode_alone.c:fuzz_code
Line
Count
Source
28
3.31k
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
3.31k
  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
3.31k
  stream->next_in = inbuf;
36
3.31k
  stream->avail_in = inbuf_size / 2;
37
38
3.31k
  lzma_action action = LZMA_RUN;
39
40
3.31k
  lzma_ret ret;
41
247k
  do {
42
247k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
3.34k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
3.34k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
3.34k
      stream->next_in = inbuf;
47
3.34k
      stream->avail_in = chunk_size;
48
49
3.34k
      inbuf += chunk_size;
50
3.34k
      inbuf_size -= chunk_size;
51
52
3.34k
      if (inbuf_size == 0)
53
3.28k
        action = LZMA_FINISH;
54
3.34k
    }
55
56
247k
    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
240k
      stream->next_out = outbuf;
61
240k
      stream->avail_out = sizeof(outbuf);
62
240k
    }
63
247k
  } 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
3.31k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
3.31k
}
fuzz_encode_stream.c:fuzz_code
Line
Count
Source
28
4.14k
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
4.14k
  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
4.14k
  stream->next_in = inbuf;
36
4.14k
  stream->avail_in = inbuf_size / 2;
37
38
4.14k
  lzma_action action = LZMA_RUN;
39
40
4.14k
  lzma_ret ret;
41
8.54k
  do {
42
8.54k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
4.37k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
4.37k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
4.37k
      stream->next_in = inbuf;
47
4.37k
      stream->avail_in = chunk_size;
48
49
4.37k
      inbuf += chunk_size;
50
4.37k
      inbuf_size -= chunk_size;
51
52
4.37k
      if (inbuf_size == 0)
53
4.13k
        action = LZMA_FINISH;
54
4.37k
    }
55
56
8.54k
    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
4.16k
      stream->next_out = outbuf;
61
4.16k
      stream->avail_out = sizeof(outbuf);
62
4.16k
    }
63
8.54k
  } 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
4.14k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
4.14k
}