Coverage Report

Created: 2024-05-21 06:41

/src/libjxl/tools/icc_codec_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 <cstring>
11
12
#include "lib/jxl/enc_icc_codec.h"
13
14
#ifdef JXL_ICC_FUZZER_SLOW_TEST
15
#include "lib/jxl/base/span.h"
16
#include "lib/jxl/dec_bit_reader.h"
17
#endif
18
19
#include "lib/jxl/base/status.h"
20
#include "lib/jxl/padded_bytes.h"
21
#include "lib/jxl/test_utils.h"
22
23
namespace jxl {
24
Status PredictICC(const uint8_t* icc, size_t size, PaddedBytes* result);
25
Status UnpredictICC(const uint8_t* enc, size_t size, PaddedBytes* result);
26
}  // namespace jxl
27
28
namespace {
29
30
using ::jxl::PaddedBytes;
31
32
#ifdef JXL_ICC_FUZZER_SLOW_TEST
33
using ::jxl::BitReader;
34
using ::jxl::Span;
35
#endif
36
37
4.14k
int DoTestOneInput(const uint8_t* data, size_t size) {
38
#if defined(JXL_ICC_FUZZER_ONLY_WRITE)
39
  bool read = false;
40
#elif defined(JXL_ICC_FUZZER_ONLY_READ)
41
  bool read = true;
42
#else
43
  // Decide whether to test the reader or the writer (both use parsing)
44
4.14k
  if (!size) return 0;
45
4.14k
  bool read = data[0] == 0;
46
4.14k
  data++;
47
4.14k
  size--;
48
4.14k
#endif
49
4.14k
  JxlMemoryManager* memory_manager = jxl::test::MemoryManager();
50
51
#ifdef JXL_ICC_FUZZER_SLOW_TEST
52
  // Including JPEG XL LZ77 and ANS compression. These are already fuzzed
53
  // separately, so it is better to disable JXL_ICC_FUZZER_SLOW_TEST to focus on
54
  // the ICC parsing.
55
  if (read) {
56
    // Reading parses the compressed format.
57
    BitReader br(Bytes(data, size));
58
    std::vector<uint8_t> result;
59
    (void)jxl::test::ReadICC(&br, &result);
60
    (void)br.Close();
61
  } else {
62
    // Writing parses the original ICC profile.
63
    PaddedBytes icc{memory_manager};
64
    icc.assign(data, data + size);
65
    BitWriter writer{memory_manager};
66
    // Writing should support any random bytestream so must succeed, make
67
    // fuzzer fail if not.
68
    JXL_ASSERT(jxl::WriteICC(icc, &writer, 0, nullptr));
69
  }
70
#else  // JXL_ICC_FUZZER_SLOW_TEST
71
4.14k
  if (read) {
72
    // Reading (unpredicting) parses the compressed format.
73
1.19k
    PaddedBytes result{memory_manager};
74
1.19k
    (void)jxl::UnpredictICC(data, size, &result);
75
2.95k
  } else {
76
    // Writing (predicting) parses the original ICC profile.
77
2.95k
    PaddedBytes result{memory_manager};
78
    // Writing should support any random bytestream so must succeed, make
79
    // fuzzer fail if not.
80
2.95k
    JXL_ASSERT(jxl::PredictICC(data, size, &result));
81
2.95k
    PaddedBytes reconstructed{memory_manager};
82
2.95k
    JXL_ASSERT(jxl::UnpredictICC(result.data(), result.size(), &reconstructed));
83
2.95k
    JXL_ASSERT(reconstructed.size() == size);
84
2.95k
    JXL_ASSERT(memcmp(data, reconstructed.data(), size) == 0);
85
2.95k
  }
86
4.14k
#endif  // JXL_ICC_FUZZER_SLOW_TEST
87
4.14k
  return 0;
88
4.14k
}
89
90
}  // namespace
91
92
32.6k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
93
32.6k
  return DoTestOneInput(data, size);
94
32.6k
}
95
96
0
void TestOneInput(const std::vector<uint8_t>& data) {
97
0
  DoTestOneInput(data.data(), data.size());
98
0
}
99
100
FUZZ_TEST(IccCodecFuzzTest, TestOneInput);