Coverage Report

Created: 2024-07-27 06:12

/src/lzma-fuzz/lzma2enc_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 "Lzma2Enc.h"
28
#include "Lzma2Dec.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
8.26k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
37
8.26k
  if (size <= 10 || size > kMaxInputSize) {
38
16
    return 0;
39
16
  }
40
41
8.24k
  CLzma2EncProps props;
42
8.24k
  Byte props_data;
43
44
8.24k
  memset(&props, 0, sizeof(props));
45
8.24k
  Lzma2EncProps_Init(&props);
46
8.24k
  props.lzmaProps.level = data[0] <= 9 ? data[0] : 9;
47
8.24k
  props.lzmaProps.lc = data[1] <= 8 ? data[1] : 8;
48
8.24k
  props.lzmaProps.lp = data[2] <= 4 ? data[2] : 4;
49
8.24k
  props.lzmaProps.pb = data[3] <= 4 ? data[3] : 4;
50
8.24k
  props.lzmaProps.algo = data[4] ? 1 : 0;
51
8.24k
  props.lzmaProps.fb = 5 + data[5];
52
8.24k
  props.lzmaProps.btMode = data[6] ? 1 : 0;
53
8.24k
  props.lzmaProps.numHashBytes = 2 + (data[7] % 3);
54
8.24k
  props.lzmaProps.mc = 1 + data[8];
55
8.24k
  props.lzmaProps.writeEndMark = data[9] ? 1 : 0;
56
8.24k
  props.lzmaProps.dictSize = 1 << 24;
57
8.24k
  data += 10;
58
8.24k
  size -= 10;
59
8.24k
  Lzma2EncProps_Normalize(&props);
60
61
8.24k
  CLzma2EncHandle enc = Lzma2Enc_Create(&CommonAlloc, &CommonAlloc);
62
8.24k
  if (!enc) {
63
0
    return 0;
64
0
  }
65
66
8.24k
  OutputBuffer out_buffer;
67
8.24k
  InputBuffer in_buffer(data, size);
68
8.24k
  Byte *dest = nullptr;
69
8.24k
  SizeT srcLen;
70
8.24k
  SizeT destLen;
71
8.24k
  ELzmaStatus status;
72
73
8.24k
  SRes res = Lzma2Enc_SetProps(enc, &props);
74
8.24k
  if (res != SZ_OK) {
75
14
    goto exit;
76
14
  }
77
78
8.23k
  Lzma2Enc_SetDataSize(enc, size);
79
8.23k
  props_data = Lzma2Enc_WriteProperties(enc);
80
81
8.23k
  res = Lzma2Enc_Encode2(enc, out_buffer.stream(), nullptr, 0,
82
8.23k
      in_buffer.stream(), nullptr, 0, nullptr);
83
8.23k
  assert(res == SZ_OK);
84
8.23k
  assert(out_buffer.size() > 0);
85
86
  // Decompress and compare with input data.
87
8.23k
  dest = static_cast<Byte*>(malloc(size));
88
8.23k
  assert(dest);
89
8.23k
  destLen = size;
90
8.23k
  srcLen = out_buffer.size();
91
92
8.23k
  res = Lzma2Decode(dest, &destLen, out_buffer.data(), &srcLen, props_data,
93
8.23k
      LZMA_FINISH_END, &status, &CommonAlloc);
94
8.23k
  assert(res == SZ_OK);
95
8.23k
  assert(status == LZMA_STATUS_FINISHED_WITH_MARK ||
96
8.23k
      status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK);
97
8.23k
  assert(srcLen == out_buffer.size());
98
8.23k
  assert(memcmp(dest, data, size) == 0);
99
100
8.24k
exit:
101
8.24k
  Lzma2Enc_Destroy(enc);
102
8.24k
  free(dest);
103
8.24k
  return 0;
104
8.23k
}