Coverage Report

Created: 2026-08-08 06:57

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
57.8k
#define MEM_LIMIT (300 << 20) // 300 MiB
22
23
// Amount of input to pass to lzma_code() per call at most.
24
76.8k
#define IN_CHUNK_SIZE 2047
25
26
27
static void
28
18.5k
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.5k
  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.5k
  stream->next_in = inbuf;
36
18.5k
  stream->avail_in = inbuf_size / 2;
37
38
18.5k
  lzma_action action = LZMA_RUN;
39
40
18.5k
  lzma_ret ret;
41
454k
  do {
42
454k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
47.3k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
47.3k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
47.3k
      stream->next_in = inbuf;
47
47.3k
      stream->avail_in = chunk_size;
48
49
47.3k
      inbuf += chunk_size;
50
47.3k
      inbuf_size -= chunk_size;
51
52
47.3k
      if (inbuf_size == 0)
53
17.8k
        action = LZMA_FINISH;
54
47.3k
    }
55
56
454k
    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
397k
      stream->next_out = outbuf;
61
397k
      stream->avail_out = sizeof(outbuf);
62
397k
    }
63
454k
  } 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.5k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
18.5k
}
fuzz_decode_stream_mt.c:fuzz_code
Line
Count
Source
28
5.87k
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.87k
  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.87k
  stream->next_in = inbuf;
36
5.87k
  stream->avail_in = inbuf_size / 2;
37
38
5.87k
  lzma_action action = LZMA_RUN;
39
40
5.87k
  lzma_ret ret;
41
83.1k
  do {
42
83.1k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
21.3k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
21.3k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
21.3k
      stream->next_in = inbuf;
47
21.3k
      stream->avail_in = chunk_size;
48
49
21.3k
      inbuf += chunk_size;
50
21.3k
      inbuf_size -= chunk_size;
51
52
21.3k
      if (inbuf_size == 0)
53
5.58k
        action = LZMA_FINISH;
54
21.3k
    }
55
56
83.1k
    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
58.7k
      stream->next_out = outbuf;
61
58.7k
      stream->avail_out = sizeof(outbuf);
62
58.7k
    }
63
83.1k
  } 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.87k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.87k
}
fuzz_decode_stream.c:fuzz_code
Line
Count
Source
28
5.20k
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.20k
  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.20k
  stream->next_in = inbuf;
36
5.20k
  stream->avail_in = inbuf_size / 2;
37
38
5.20k
  lzma_action action = LZMA_RUN;
39
40
5.20k
  lzma_ret ret;
41
60.4k
  do {
42
60.4k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
18.2k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
18.2k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
18.2k
      stream->next_in = inbuf;
47
18.2k
      stream->avail_in = chunk_size;
48
49
18.2k
      inbuf += chunk_size;
50
18.2k
      inbuf_size -= chunk_size;
51
52
18.2k
      if (inbuf_size == 0)
53
4.85k
        action = LZMA_FINISH;
54
18.2k
    }
55
56
60.4k
    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
38.9k
      stream->next_out = outbuf;
61
38.9k
      stream->avail_out = sizeof(outbuf);
62
38.9k
    }
63
60.4k
  } 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.20k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.20k
}
fuzz_decode_alone.c:fuzz_code
Line
Count
Source
28
3.37k
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.37k
  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.37k
  stream->next_in = inbuf;
36
3.37k
  stream->avail_in = inbuf_size / 2;
37
38
3.37k
  lzma_action action = LZMA_RUN;
39
40
3.37k
  lzma_ret ret;
41
302k
  do {
42
302k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
3.41k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
3.41k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
3.41k
      stream->next_in = inbuf;
47
3.41k
      stream->avail_in = chunk_size;
48
49
3.41k
      inbuf += chunk_size;
50
3.41k
      inbuf_size -= chunk_size;
51
52
3.41k
      if (inbuf_size == 0)
53
3.34k
        action = LZMA_FINISH;
54
3.41k
    }
55
56
302k
    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
295k
      stream->next_out = outbuf;
61
295k
      stream->avail_out = sizeof(outbuf);
62
295k
    }
63
302k
  } 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.37k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
3.37k
}
fuzz_encode_stream.c:fuzz_code
Line
Count
Source
28
4.07k
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.07k
  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.07k
  stream->next_in = inbuf;
36
4.07k
  stream->avail_in = inbuf_size / 2;
37
38
4.07k
  lzma_action action = LZMA_RUN;
39
40
4.07k
  lzma_ret ret;
41
8.38k
  do {
42
8.38k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
4.29k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
4.29k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
4.29k
      stream->next_in = inbuf;
47
4.29k
      stream->avail_in = chunk_size;
48
49
4.29k
      inbuf += chunk_size;
50
4.29k
      inbuf_size -= chunk_size;
51
52
4.29k
      if (inbuf_size == 0)
53
4.07k
        action = LZMA_FINISH;
54
4.29k
    }
55
56
8.38k
    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.09k
      stream->next_out = outbuf;
61
4.09k
      stream->avail_out = sizeof(outbuf);
62
4.09k
    }
63
8.38k
  } 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.07k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
4.07k
}