Coverage Report

Created: 2026-09-01 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/curl_fuzzer/proto_fuzzer/fuzzer_main.h
Line
Count
Source
1
/*
2
 * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al.
3
 *
4
 * SPDX-License-Identifier: curl
5
 */
6
7
/// @file
8
/// @brief Shared byte-to-protobuf dispatch for the policy-split fuzzers.
9
10
#ifndef PROTO_FUZZER_FUZZER_MAIN_H_
11
#define PROTO_FUZZER_FUZZER_MAIN_H_
12
13
#include <cstddef>
14
#include <cstdint>
15
16
#include "proto_fuzzer/target_profile.h"
17
18
namespace proto_fuzzer {
19
20
/// Decode and run one serialized Scenario. Keeping this behind an ordinary
21
/// function allows each binary to expose a discoverable, same-named libFuzzer
22
/// entrypoint while retaining one mutation and execution implementation. The
23
/// profile is explicit so target identity remains visible at the entrypoint
24
/// instead of being hidden in per-translation-unit compiler definitions.
25
/// @param profile Mutation and execution policy selected by the entrypoint.
26
/// @param data Serialized binary Scenario bytes.
27
/// @param size Number of bytes available at data.
28
/// @return Always zero, as required by libFuzzer.
29
int ProtoFuzzerTestOneInput(TargetProfile profile, const std::uint8_t* data, std::size_t size);
30
31
/// Mutate a serialized Scenario while preserving the selected lane's policy.
32
/// @param profile Mutation and execution policy selected by the entrypoint.
33
/// @param data Mutable serialized Scenario storage.
34
/// @param size Current serialized size.
35
/// @param max_size Capacity of data.
36
/// @param seed Mutation random seed supplied by libFuzzer.
37
/// @return Serialized size after mutation.
38
std::size_t ProtoFuzzerCustomMutator(TargetProfile profile, std::uint8_t* data, std::size_t size, std::size_t max_size,
39
                                     unsigned int seed);
40
41
/// Cross two serialized Scenarios while preserving the selected lane's policy.
42
/// @param profile Mutation and execution policy selected by the entrypoint.
43
/// @param data1 First serialized parent.
44
/// @param size1 Size of data1.
45
/// @param data2 Second serialized parent.
46
/// @param size2 Size of data2.
47
/// @param out Destination storage.
48
/// @param max_out_size Capacity of out.
49
/// @param seed Crossover random seed supplied by libFuzzer.
50
/// @return Serialized child size.
51
std::size_t ProtoFuzzerCustomCrossOver(TargetProfile profile, const std::uint8_t* data1, std::size_t size1,
52
                                       const std::uint8_t* data2, std::size_t size2, std::uint8_t* out,
53
                                       std::size_t max_out_size, unsigned int seed);
54
55
/// Binds a concrete profile once in each thin entrypoint source. This adapter
56
/// keeps libFuzzer's C ABI boilerplate uniform without making target selection
57
/// an invisible compile-time side effect in the shared implementation.
58
/// @tparam Profile Fixed identity of the binary exposing these callbacks.
59
template <TargetProfile Profile>
60
struct ProtoFuzzerEntrypoint {
61
  /// Forward a corpus input with the profile fixed by this binary. Keeping the
62
  /// profile out of the C ABI prevents libFuzzer from choosing it while still
63
  /// making the binding explicit in the entrypoint source.
64
  /// @param data Serialized binary Scenario bytes.
65
  /// @param size Number of bytes available at data.
66
  /// @return Always zero, as required by libFuzzer.
67
38.5k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
38.5k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
38.5k
  }
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)6>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
2.57k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
2.57k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
2.57k
  }
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)7>::TestOneInput(unsigned char const*, unsigned long)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)8>::TestOneInput(unsigned char const*, unsigned long)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)4>::TestOneInput(unsigned char const*, unsigned long)
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)2>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
4.94k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
4.94k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
4.94k
  }
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)3>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
3.73k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
3.73k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
3.73k
  }
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)10>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
3.70k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
3.70k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
3.70k
  }
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)0>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
15.8k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
15.8k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
15.8k
  }
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)1>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
4.51k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
4.51k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
4.51k
  }
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)9>::TestOneInput(unsigned char const*, unsigned long)
proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)5>::TestOneInput(unsigned char const*, unsigned long)
Line
Count
Source
67
3.20k
  static int TestOneInput(const std::uint8_t* data, std::size_t size) {
68
3.20k
    return ProtoFuzzerTestOneInput(Profile, data, size);
69
3.20k
  }
70
71
  /// Forward mutation through the same fixed profile used for execution so a
72
  /// lane cannot accumulate inputs that its runner will immediately discard.
73
  /// @param data Mutable serialized Scenario storage.
74
  /// @param size Current serialized size.
75
  /// @param max_size Capacity of data.
76
  /// @param seed Mutation random seed supplied by libFuzzer.
77
  /// @return Serialized size after mutation.
78
0
  static std::size_t CustomMutator(std::uint8_t* data, std::size_t size, std::size_t max_size, unsigned int seed) {
79
0
    return ProtoFuzzerCustomMutator(Profile, data, size, max_size, seed);
80
0
  }
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)6>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)7>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)8>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)4>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)2>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)3>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)10>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)0>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)1>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)9>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)5>::CustomMutator(unsigned char*, unsigned long, unsigned long, unsigned int)
81
82
  /// Forward crossover through the fixed profile so children are normalized
83
  /// for the same lane as both ordinary mutations and execution.
84
  /// @param data1 First serialized parent.
85
  /// @param size1 Size of data1.
86
  /// @param data2 Second serialized parent.
87
  /// @param size2 Size of data2.
88
  /// @param out Destination storage.
89
  /// @param max_out_size Capacity of out.
90
  /// @param seed Crossover random seed supplied by libFuzzer.
91
  /// @return Serialized child size.
92
  static std::size_t CustomCrossOver(const std::uint8_t* data1, std::size_t size1, const std::uint8_t* data2,
93
                                     std::size_t size2, std::uint8_t* out, std::size_t max_out_size,
94
0
                                     unsigned int seed) {
95
0
    return ProtoFuzzerCustomCrossOver(Profile, data1, size1, data2, size2, out, max_out_size, seed);
96
0
  }
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)6>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)7>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)8>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)4>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)2>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)3>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)10>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)0>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)1>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)9>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
Unexecuted instantiation: proto_fuzzer::ProtoFuzzerEntrypoint<(proto_fuzzer::TargetProfile)5>::CustomCrossOver(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int)
97
};
98
99
}  // namespace proto_fuzzer
100
101
#endif  // PROTO_FUZZER_FUZZER_MAIN_H_