Coverage Report

Created: 2025-12-05 06:34

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
53.3k
#define MEM_LIMIT (300 << 20) // 300 MiB
22
23
// Amount of input to pass to lzma_code() per call at most.
24
78.0k
#define IN_CHUNK_SIZE 2047
25
26
27
static void
28
17.3k
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
17.3k
  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
17.3k
  stream->next_in = inbuf;
36
17.3k
  stream->avail_in = inbuf_size / 2;
37
38
17.3k
  lzma_action action = LZMA_RUN;
39
40
17.3k
  lzma_ret ret;
41
414k
  do {
42
414k
    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
16.6k
        action = LZMA_FINISH;
54
47.3k
    }
55
56
414k
    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
358k
      stream->next_out = outbuf;
61
358k
      stream->avail_out = sizeof(outbuf);
62
358k
    }
63
414k
  } 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
17.3k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
17.3k
}
fuzz_decode_stream_mt.c:fuzz_code
Line
Count
Source
28
5.49k
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.49k
  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.49k
  stream->next_in = inbuf;
36
5.49k
  stream->avail_in = inbuf_size / 2;
37
38
5.49k
  lzma_action action = LZMA_RUN;
39
40
5.49k
  lzma_ret ret;
41
76.1k
  do {
42
76.1k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
22.4k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
22.4k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
22.4k
      stream->next_in = inbuf;
47
22.4k
      stream->avail_in = chunk_size;
48
49
22.4k
      inbuf += chunk_size;
50
22.4k
      inbuf_size -= chunk_size;
51
52
22.4k
      if (inbuf_size == 0)
53
5.18k
        action = LZMA_FINISH;
54
22.4k
    }
55
56
76.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
50.9k
      stream->next_out = outbuf;
61
50.9k
      stream->avail_out = sizeof(outbuf);
62
50.9k
    }
63
76.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.49k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
5.49k
}
fuzz_decode_stream.c:fuzz_code
Line
Count
Source
28
4.70k
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.70k
  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.70k
  stream->next_in = inbuf;
36
4.70k
  stream->avail_in = inbuf_size / 2;
37
38
4.70k
  lzma_action action = LZMA_RUN;
39
40
4.70k
  lzma_ret ret;
41
55.6k
  do {
42
55.6k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
17.5k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
17.5k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
17.5k
      stream->next_in = inbuf;
47
17.5k
      stream->avail_in = chunk_size;
48
49
17.5k
      inbuf += chunk_size;
50
17.5k
      inbuf_size -= chunk_size;
51
52
17.5k
      if (inbuf_size == 0)
53
4.35k
        action = LZMA_FINISH;
54
17.5k
    }
55
56
55.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
35.3k
      stream->next_out = outbuf;
61
35.3k
      stream->avail_out = sizeof(outbuf);
62
35.3k
    }
63
55.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
4.70k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
4.70k
}
fuzz_decode_alone.c:fuzz_code
Line
Count
Source
28
3.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
3.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
3.14k
  stream->next_in = inbuf;
36
3.14k
  stream->avail_in = inbuf_size / 2;
37
38
3.14k
  lzma_action action = LZMA_RUN;
39
40
3.14k
  lzma_ret ret;
41
274k
  do {
42
274k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
3.16k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
3.16k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
3.16k
      stream->next_in = inbuf;
47
3.16k
      stream->avail_in = chunk_size;
48
49
3.16k
      inbuf += chunk_size;
50
3.16k
      inbuf_size -= chunk_size;
51
52
3.16k
      if (inbuf_size == 0)
53
3.10k
        action = LZMA_FINISH;
54
3.16k
    }
55
56
274k
    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
268k
      stream->next_out = outbuf;
61
268k
      stream->avail_out = sizeof(outbuf);
62
268k
    }
63
274k
  } 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.14k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
3.14k
}
fuzz_encode_stream.c:fuzz_code
Line
Count
Source
28
3.99k
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.99k
  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.99k
  stream->next_in = inbuf;
36
3.99k
  stream->avail_in = inbuf_size / 2;
37
38
3.99k
  lzma_action action = LZMA_RUN;
39
40
3.99k
  lzma_ret ret;
41
8.22k
  do {
42
8.22k
    if (stream->avail_in == 0 && inbuf_size > 0) {
43
4.20k
      const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
44
4.20k
          ? inbuf_size : IN_CHUNK_SIZE;
45
46
4.20k
      stream->next_in = inbuf;
47
4.20k
      stream->avail_in = chunk_size;
48
49
4.20k
      inbuf += chunk_size;
50
4.20k
      inbuf_size -= chunk_size;
51
52
4.20k
      if (inbuf_size == 0)
53
3.98k
        action = LZMA_FINISH;
54
4.20k
    }
55
56
8.22k
    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.01k
      stream->next_out = outbuf;
61
4.01k
      stream->avail_out = sizeof(outbuf);
62
4.01k
    }
63
8.22k
  } 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.99k
  if (ret == LZMA_PROG_ERROR) {
69
    fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
70
0
    abort();
71
0
  }
72
3.99k
}