Coverage Report

Created: 2025-06-13 06:39

/src/libjxl/tools/rans_fuzzer.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2
//
3
// Use of this source code is governed by a BSD-style
4
// license that can be found in the LICENSE file.
5
6
#include <jxl/memory_manager.h>
7
8
#include <cstddef>
9
#include <cstdint>
10
#include <vector>
11
12
#include "lib/jxl/base/common.h"
13
#include "lib/jxl/base/compiler_specific.h"
14
#include "lib/jxl/base/span.h"
15
#include "lib/jxl/base/status.h"
16
#include "lib/jxl/dec_ans.h"
17
#include "lib/jxl/dec_bit_reader.h"
18
#include "lib/jxl/fuzztest.h"
19
#include "tools/tracking_memory_manager.h"
20
21
namespace {
22
23
using ::jpegxl::tools::kGiB;
24
using ::jpegxl::tools::TrackingMemoryManager;
25
using ::jxl::ANSCode;
26
using ::jxl::ANSSymbolReader;
27
using ::jxl::BitReader;
28
using ::jxl::BitReaderScopedCloser;
29
using ::jxl::Bytes;
30
using ::jxl::Status;
31
32
2.09k
void Check(bool ok) {
33
2.09k
  if (!ok) {
34
0
    JXL_CRASH();
35
0
  }
36
2.09k
}
37
38
Status Run(const uint8_t* data, size_t size, JxlMemoryManager* memory_manager,
39
2.09k
           size_t num_contexts) {
40
2.09k
  std::vector<uint8_t> context_map;
41
2.09k
  Status ret = true;
42
2.09k
  {
43
2.09k
    BitReader br(Bytes(data, size));
44
2.09k
    BitReaderScopedCloser br_closer(br, ret);
45
2.09k
    ANSCode code;
46
2.09k
    JXL_RETURN_IF_ERROR(DecodeHistograms(memory_manager, &br, num_contexts,
47
2.09k
                                         &code, &context_map));
48
1.42k
    JXL_ASSIGN_OR_RETURN(ANSSymbolReader ansreader,
49
1.42k
                         ANSSymbolReader::Create(&code, &br));
50
51
    // Limit the maximum amount of reads to avoid (valid) infinite loops.
52
1.42k
    const size_t maxreads = size * 8;
53
1.42k
    size_t numreads = 0;
54
1.42k
    int context = 0;
55
67.9M
    while (jxl::DivCeil(br.TotalBitsConsumed(), jxl::kBitsPerByte) < size &&
56
67.9M
           numreads <= maxreads) {
57
67.9M
      int code = ansreader.ReadHybridUint(context, &br, context_map);
58
67.9M
      context = code % num_contexts;
59
67.9M
      numreads++;
60
67.9M
    }
61
1.42k
  }
62
0
  return true;
63
1.42k
}
64
65
2.09k
int DoTestOneInput(const uint8_t* data, size_t size) {
66
2.09k
  if (size < 2) return 0;
67
2.09k
  size_t numContexts = data[0] * 256 * data[1] + 1;
68
2.09k
  data += 2;
69
2.09k
  size -= 2;
70
71
2.09k
  TrackingMemoryManager memory_manager{/* cap */ 1 * kGiB,
72
2.09k
                                       /* total_cap */ 5 * kGiB};
73
  // It is OK to fail.
74
2.09k
  (void)Run(data, size, memory_manager.get(), numContexts);
75
2.09k
  Check(memory_manager.Reset());
76
77
2.09k
  return 0;
78
2.09k
}
79
80
}  // namespace
81
82
2.09k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
83
2.09k
  return DoTestOneInput(data, size);
84
2.09k
}
85
86
0
void TestOneInput(const std::vector<uint8_t>& data) {
87
0
  DoTestOneInput(data.data(), data.size());
88
0
}
89
90
FUZZ_TEST(RansFuzzTest, TestOneInput);