Coverage Report

Created: 2026-08-13 07:11

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
59.2k
#define MEM_LIMIT (300 << 20) // 300 MiB
22
23
// Amount of input to pass to lzma_code() per call at most.
24
78.8k
#define IN_CHUNK_SIZE 2047
25
26
27
static void
28
18.8k
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.8k
  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.8k
  stream->next_in = inbuf;
36
18.8k
  stream->avail_in = inbuf_size / 2;
37
38
18.8k
  lzma_action action = LZMA_RUN;
39
40
18.8k
  lzma_ret ret;
41
426k
  do {
42
426k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
48.5k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
48.5k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
48.5k
      stream->next_in = inbuf;
47
48.5k
      stream->avail_in = chunk_size;
48
49
48.5k
      inbuf += chunk_size;
50
48.5k
      inbuf_size -= chunk_size;
51
52
48.5k
      if (inbuf_size == 0)
53
18.2k
        action = LZMA_FINISH;
54
48.5k
    }
55
56
426k
    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
367k
      stream->next_out = outbuf;
61
367k
      stream->avail_out = sizeof(outbuf);
62
367k
    }
63
426k
  } 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.8k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
18.8k
}
fuzz_decode_stream_mt.c:fuzz_code
Line
Count
Source
28
5.92k
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.92k
  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.92k
  stream->next_in = inbuf;
36
5.92k
  stream->avail_in = inbuf_size / 2;
37
38
5.92k
  lzma_action action = LZMA_RUN;
39
40
5.92k
  lzma_ret ret;
41
85.0k
  do {
42
85.0k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
21.7k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
21.7k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
21.7k
      stream->next_in = inbuf;
47
21.7k
      stream->avail_in = chunk_size;
48
49
21.7k
      inbuf += chunk_size;
50
21.7k
      inbuf_size -= chunk_size;
51
52
21.7k
      if (inbuf_size == 0)
53
5.64k
        action = LZMA_FINISH;
54
21.7k
    }
55
56
85.0k
    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
60.0k
      stream->next_out = outbuf;
61
60.0k
      stream->avail_out = sizeof(outbuf);
62
60.0k
    }
63
85.0k
  } 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.92k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.92k
}
fuzz_decode_stream.c:fuzz_code
Line
Count
Source
28
5.36k
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.36k
  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.36k
  stream->next_in = inbuf;
36
5.36k
  stream->avail_in = inbuf_size / 2;
37
38
5.36k
  lzma_action action = LZMA_RUN;
39
40
5.36k
  lzma_ret ret;
41
61.6k
  do {
42
61.6k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
18.9k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
18.9k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
18.9k
      stream->next_in = inbuf;
47
18.9k
      stream->avail_in = chunk_size;
48
49
18.9k
      inbuf += chunk_size;
50
18.9k
      inbuf_size -= chunk_size;
51
52
18.9k
      if (inbuf_size == 0)
53
5.03k
        action = LZMA_FINISH;
54
18.9k
    }
55
56
61.6k
    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
39.3k
      stream->next_out = outbuf;
61
39.3k
      stream->avail_out = sizeof(outbuf);
62
39.3k
    }
63
61.6k
  } 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.36k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.36k
}
fuzz_decode_alone.c:fuzz_code
Line
Count
Source
28
3.51k
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.51k
  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.51k
  stream->next_in = inbuf;
36
3.51k
  stream->avail_in = inbuf_size / 2;
37
38
3.51k
  lzma_action action = LZMA_RUN;
39
40
3.51k
  lzma_ret ret;
41
271k
  do {
42
271k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
3.55k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
3.55k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
3.55k
      stream->next_in = inbuf;
47
3.55k
      stream->avail_in = chunk_size;
48
49
3.55k
      inbuf += chunk_size;
50
3.55k
      inbuf_size -= chunk_size;
51
52
3.55k
      if (inbuf_size == 0)
53
3.48k
        action = LZMA_FINISH;
54
3.55k
    }
55
56
271k
    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
264k
      stream->next_out = outbuf;
61
264k
      stream->avail_out = sizeof(outbuf);
62
264k
    }
63
271k
  } 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.51k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
3.51k
}
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
}