Coverage Report

Created: 2024-07-27 06:17

/src/lzma-fuzz/lzmaenc_fuzzer.cc
Line
Count
Source (jump to first uncovered line)
1
/**
2
 *
3
 * @copyright Copyright (c) 2019 Joachim Bauch <mail@joachim-bauch.de>
4
 *
5
 * @license GNU GPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
#include <assert.h>
23
#include <stdint.h>
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include "LzmaEnc.h"
28
#include "LzmaDec.h"
29
30
#include "common-alloc.h"
31
#include "common-buffer.h"
32
33
// Limit maximum size to avoid running into timeouts with too large data.
34
static const size_t kMaxInputSize = 100 * 1024;
35
36
7.56k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
37
7.56k
  if (size <= 10 || size > kMaxInputSize) {
38
9
    return 0;
39
9
  }
40
41
7.55k
  CLzmaEncProps props = {0};
42
7.55k
  Byte props_data[LZMA_PROPS_SIZE];
43
7.55k
  SizeT props_size = LZMA_PROPS_SIZE;
44
45
7.55k
  LzmaEncProps_Init(&props);
46
7.55k
  props.level = data[0] <= 9 ? data[0] : 9;
47
7.55k
  props.lc = data[1] <= 8 ? data[1] : 8;
48
7.55k
  props.lp = data[2] <= 4 ? data[2] : 4;
49
7.55k
  props.pb = data[3] <= 4 ? data[3] : 4;
50
7.55k
  props.algo = data[4] ? 1 : 0;
51
7.55k
  props.fb = 5 + data[5];
52
7.55k
  props.btMode = data[6] ? 1 : 0;
53
7.55k
  props.numHashBytes = 2 + (data[7] % 3);
54
7.55k
  props.mc = 1 + data[8];
55
7.55k
  props.writeEndMark = data[9] ? 1 : 0;
56
7.55k
  props.dictSize = 1 << 24;
57
7.55k
  data += 10;
58
7.55k
  size -= 10;
59
7.55k
  LzmaEncProps_Normalize(&props);
60
61
7.55k
  CLzmaEncHandle enc = LzmaEnc_Create(&CommonAlloc);
62
7.55k
  if (!enc) {
63
0
    return 0;
64
0
  }
65
66
7.55k
  OutputBuffer out_buffer;
67
7.55k
  InputBuffer in_buffer(data, size);
68
7.55k
  Byte *dest = nullptr;
69
7.55k
  SizeT srcLen;
70
7.55k
  SizeT destLen;
71
7.55k
  ELzmaStatus status;
72
73
7.55k
  SRes res = LzmaEnc_SetProps(enc, &props);
74
7.55k
  if (res != SZ_OK) {
75
0
    goto exit;
76
0
  }
77
78
7.55k
  LzmaEnc_SetDataSize(enc, size);
79
7.55k
  if (LzmaEnc_WriteProperties(enc, props_data, &props_size) != SZ_OK) {
80
0
    goto exit;
81
0
  }
82
7.55k
  assert(props_size == LZMA_PROPS_SIZE);
83
84
7.55k
  res = LzmaEnc_Encode(enc, out_buffer.stream(), in_buffer.stream(), nullptr,
85
7.55k
      &CommonAlloc, &CommonAlloc);
86
7.55k
  assert(res == SZ_OK);
87
7.55k
  assert(out_buffer.size() > 0);
88
89
  // Decompress and compare with input data.
90
7.55k
  dest = static_cast<Byte*>(malloc(size));
91
7.55k
  assert(dest);
92
7.55k
  destLen = size;
93
7.55k
  srcLen = out_buffer.size();
94
95
7.55k
  res = LzmaDecode(dest, &destLen, out_buffer.data(), &srcLen, props_data,
96
7.55k
      props_size, LZMA_FINISH_END, &status, &CommonAlloc);
97
7.55k
  assert(res == SZ_OK);
98
7.55k
  assert(status == LZMA_STATUS_FINISHED_WITH_MARK ||
99
7.55k
      status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK);
100
7.55k
  assert(srcLen == out_buffer.size());
101
7.55k
  assert(memcmp(dest, data, size) == 0);
102
103
7.55k
exit:
104
7.55k
  LzmaEnc_Destroy(enc, &CommonAlloc, &CommonAlloc);
105
7.55k
  free(dest);
106
7.55k
  return 0;
107
7.55k
}