Coverage Report

Created: 2024-07-27 06:12

/src/lzma-fuzz/lzma2dec_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 <stdint.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "Lzma2Dec.h"
27
28
#include "common-alloc.h"
29
30
static const size_t kBufferSize = 8192;
31
32
static const size_t kMaxDictionarySize = 32 * 1024 * 1024;
33
34
// Limit maximum size to avoid running into timeouts with too large data.
35
static const size_t kMaxInputSize = 100 * 1024;
36
37
// Copied from sdk/C/Lzma2Dec.c
38
#define LZMA2_DIC_SIZE_FROM_PROP(p) \
39
10.3k
    (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
40
41
5.19k
static bool GetDictionarySize(Byte prop, size_t* size) {
42
5.19k
  if (prop > 40) {
43
4
    return false;
44
4
  }
45
46
5.18k
  *size = (prop == 40)
47
5.18k
      ? 0xFFFFFFFF
48
5.18k
      : LZMA2_DIC_SIZE_FROM_PROP(prop);
49
5.18k
  return true;
50
5.19k
}
51
52
5.20k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
53
5.20k
  if (size < 1 || size > kMaxInputSize) {
54
10
    return 0;
55
10
  }
56
57
5.19k
  size_t dictionarySize;
58
5.19k
  if (!GetDictionarySize(data[0], &dictionarySize)) {
59
4
    return 0;
60
4
  }
61
62
  // Avoid using too much memory.
63
5.18k
  if (dictionarySize > kMaxDictionarySize) {
64
5
    return 0;
65
5
  }
66
67
5.18k
  CLzma2Dec dec;
68
5.18k
  Lzma2Dec_Construct(&dec);
69
5.18k
  if (Lzma2Dec_Allocate(&dec, data[0], &CommonAlloc) != SZ_OK) {
70
0
    return 0;
71
0
  }
72
73
5.18k
  data += 1;
74
5.18k
  size -= 1;
75
76
5.18k
  Lzma2Dec_Init(&dec);
77
17.4k
  while (size > 0) {
78
17.3k
    Byte buf[kBufferSize];
79
17.3k
    SRes res;
80
17.3k
    SizeT srcLen = size;
81
17.3k
    SizeT destLen = kBufferSize;
82
17.3k
    ELzmaStatus status;
83
17.3k
    res = Lzma2Dec_DecodeToBuf(&dec, buf, &destLen, data, &srcLen,
84
17.3k
        LZMA_FINISH_ANY, &status);
85
17.3k
    if (res != SZ_OK || status == LZMA_STATUS_FINISHED_WITH_MARK ||
86
17.3k
        status == LZMA_STATUS_NEEDS_MORE_INPUT) {
87
5.10k
      goto exit;
88
5.10k
    }
89
90
12.2k
    size -= srcLen;
91
12.2k
    data += srcLen;
92
12.2k
  }
93
94
5.18k
exit:
95
5.18k
  Lzma2Dec_Free(&dec, &CommonAlloc);
96
5.18k
  return 0;
97
5.18k
}