Coverage Report

Created: 2026-02-26 07:01

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.7k
#define MEM_LIMIT (300 << 20) // 300 MiB
22
23
// Amount of input to pass to lzma_code() per call at most.
24
80.4k
#define IN_CHUNK_SIZE 2047
25
26
27
static void
28
18.2k
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.2k
  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.2k
  stream->next_in = inbuf;
36
18.2k
  stream->avail_in = inbuf_size / 2;
37
38
18.2k
  lzma_action action = LZMA_RUN;
39
40
18.2k
  lzma_ret ret;
41
391k
  do {
42
391k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
48.9k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
48.9k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
48.9k
      stream->next_in = inbuf;
47
48.9k
      stream->avail_in = chunk_size;
48
49
48.9k
      inbuf += chunk_size;
50
48.9k
      inbuf_size -= chunk_size;
51
52
48.9k
      if (inbuf_size == 0)
53
17.5k
        action = LZMA_FINISH;
54
48.9k
    }
55
56
391k
    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
332k
      stream->next_out = outbuf;
61
332k
      stream->avail_out = sizeof(outbuf);
62
332k
    }
63
391k
  } 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.2k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
18.2k
}
fuzz_decode_stream_mt.c:fuzz_code
Line
Count
Source
28
5.89k
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.89k
  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.89k
  stream->next_in = inbuf;
36
5.89k
  stream->avail_in = inbuf_size / 2;
37
38
5.89k
  lzma_action action = LZMA_RUN;
39
40
5.89k
  lzma_ret ret;
41
81.6k
  do {
42
81.6k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
22.7k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
22.7k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
22.7k
      stream->next_in = inbuf;
47
22.7k
      stream->avail_in = chunk_size;
48
49
22.7k
      inbuf += chunk_size;
50
22.7k
      inbuf_size -= chunk_size;
51
52
22.7k
      if (inbuf_size == 0)
53
5.59k
        action = LZMA_FINISH;
54
22.7k
    }
55
56
81.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
55.9k
      stream->next_out = outbuf;
61
55.9k
      stream->avail_out = sizeof(outbuf);
62
55.9k
    }
63
81.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.89k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.89k
}
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.33k
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.33k
  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.33k
  stream->next_in = inbuf;
36
3.33k
  stream->avail_in = inbuf_size / 2;
37
38
3.33k
  lzma_action action = LZMA_RUN;
39
40
3.33k
  lzma_ret ret;
41
241k
  do {
42
241k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
3.35k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
3.35k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
3.35k
      stream->next_in = inbuf;
47
3.35k
      stream->avail_in = chunk_size;
48
49
3.35k
      inbuf += chunk_size;
50
3.35k
      inbuf_size -= chunk_size;
51
52
3.35k
      if (inbuf_size == 0)
53
3.30k
        action = LZMA_FINISH;
54
3.35k
    }
55
56
241k
    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
235k
      stream->next_out = outbuf;
61
235k
      stream->avail_out = sizeof(outbuf);
62
235k
    }
63
241k
  } 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.33k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
3.33k
}
fuzz_encode_stream.c:fuzz_code
Line
Count
Source
28
4.08k
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.08k
  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.08k
  stream->next_in = inbuf;
36
4.08k
  stream->avail_in = inbuf_size / 2;
37
38
4.08k
  lzma_action action = LZMA_RUN;
39
40
4.08k
  lzma_ret ret;
41
8.41k
  do {
42
8.41k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
4.30k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
4.30k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
4.30k
      stream->next_in = inbuf;
47
4.30k
      stream->avail_in = chunk_size;
48
49
4.30k
      inbuf += chunk_size;
50
4.30k
      inbuf_size -= chunk_size;
51
52
4.30k
      if (inbuf_size == 0)
53
4.08k
        action = LZMA_FINISH;
54
4.30k
    }
55
56
8.41k
    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.11k
      stream->next_out = outbuf;
61
4.11k
      stream->avail_out = sizeof(outbuf);
62
4.11k
    }
63
8.41k
  } 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.08k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
4.08k
}