Coverage Report

Created: 2025-11-24 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/test/fuzz.cpp
Line
Count
Source
1
#include <cassert>
2
#include <cxxopts.hpp>
3
#include <fuzzer/FuzzedDataProvider.h>
4
5
constexpr int kMaxOptions = 1024;
6
constexpr int kMaxArgSize = 1024;
7
8
enum class ParseableTypes
9
{
10
  kInt,
11
  kString,
12
  kVectorString,
13
  kFloat,
14
  kDouble,
15
16
  // Marker for fuzzer.
17
  kMaxValue,
18
};
19
20
template <typename T>
21
void
22
add_fuzzed_option(cxxopts::Options* options, FuzzedDataProvider* provider)
23
20.3k
{
24
20.3k
  assert(options);
25
20.3k
  assert(provider);
26
27
20.3k
  options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize),
28
20.3k
                         provider->ConsumeRandomLengthString(kMaxArgSize),
29
20.3k
                         cxxopts::value<T>());
30
20.3k
}
void add_fuzzed_option<int>(cxxopts::Options*, FuzzedDataProvider*)
Line
Count
Source
23
4.05k
{
24
4.05k
  assert(options);
25
4.05k
  assert(provider);
26
27
4.05k
  options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize),
28
4.05k
                         provider->ConsumeRandomLengthString(kMaxArgSize),
29
4.05k
                         cxxopts::value<T>());
30
4.05k
}
void add_fuzzed_option<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(cxxopts::Options*, FuzzedDataProvider*)
Line
Count
Source
23
3.51k
{
24
3.51k
  assert(options);
25
3.51k
  assert(provider);
26
27
3.51k
  options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize),
28
3.51k
                         provider->ConsumeRandomLengthString(kMaxArgSize),
29
3.51k
                         cxxopts::value<T>());
30
3.51k
}
void add_fuzzed_option<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(cxxopts::Options*, FuzzedDataProvider*)
Line
Count
Source
23
5.10k
{
24
5.10k
  assert(options);
25
5.10k
  assert(provider);
26
27
5.10k
  options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize),
28
5.10k
                         provider->ConsumeRandomLengthString(kMaxArgSize),
29
5.10k
                         cxxopts::value<T>());
30
5.10k
}
void add_fuzzed_option<float>(cxxopts::Options*, FuzzedDataProvider*)
Line
Count
Source
23
5.04k
{
24
5.04k
  assert(options);
25
5.04k
  assert(provider);
26
27
5.04k
  options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize),
28
5.04k
                         provider->ConsumeRandomLengthString(kMaxArgSize),
29
5.04k
                         cxxopts::value<T>());
30
5.04k
}
void add_fuzzed_option<double>(cxxopts::Options*, FuzzedDataProvider*)
Line
Count
Source
23
2.60k
{
24
2.60k
  assert(options);
25
2.60k
  assert(provider);
26
27
2.60k
  options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize),
28
2.60k
                         provider->ConsumeRandomLengthString(kMaxArgSize),
29
2.60k
                         cxxopts::value<T>());
30
2.60k
}
31
32
extern "C" int
33
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
34
4.43k
{
35
4.43k
  try
36
4.43k
  {
37
4.43k
    FuzzedDataProvider provider(data, size);
38
39
    // Randomly generate a usage string.
40
4.43k
    cxxopts::Options options(provider.ConsumeRandomLengthString(kMaxArgSize),
41
4.43k
                             provider.ConsumeRandomLengthString(kMaxArgSize));
42
43
    // Randomly generate a set of flags configurations.
44
25.5k
    for (int i = 0; i < provider.ConsumeIntegralInRange<int>(0, kMaxOptions);
45
21.0k
         i++)
46
21.4k
    {
47
21.4k
      switch (provider.ConsumeEnum<ParseableTypes>())
48
21.4k
      {
49
4.05k
      case ParseableTypes::kInt:
50
4.05k
        add_fuzzed_option<int>(&options, &provider);
51
4.05k
        break;
52
3.51k
      case ParseableTypes::kString:
53
3.51k
        add_fuzzed_option<std::string>(&options, &provider);
54
3.51k
        break;
55
5.10k
      case ParseableTypes::kVectorString:
56
5.10k
        add_fuzzed_option<std::vector<std::string>>(&options, &provider);
57
5.10k
        break;
58
5.04k
      case ParseableTypes::kFloat:
59
5.04k
        add_fuzzed_option<float>(&options, &provider);
60
5.04k
        break;
61
2.60k
      case ParseableTypes::kDouble:
62
2.60k
        add_fuzzed_option<double>(&options, &provider);
63
2.60k
        break;
64
1.10k
      default:
65
1.10k
        break;
66
21.4k
      }
67
21.4k
    }
68
    // Sometimes allow unrecognised options.
69
4.07k
    if (provider.ConsumeBool())
70
1.38k
    {
71
1.38k
      options.allow_unrecognised_options();
72
1.38k
    }
73
    // Sometimes allow trailing positional arguments.
74
4.07k
    if (provider.ConsumeBool())
75
1.31k
    {
76
1.31k
      std::string positional_option_name =
77
1.31k
        provider.ConsumeRandomLengthString(kMaxArgSize);
78
1.31k
      options.add_options()(positional_option_name,
79
1.31k
                            provider.ConsumeRandomLengthString(kMaxArgSize),
80
1.31k
                            cxxopts::value<std::vector<std::string>>());
81
1.31k
      options.parse_positional({positional_option_name});
82
1.31k
    }
83
84
    // Build command line input.
85
4.07k
    const int argc = provider.ConsumeIntegralInRange<int>(1, kMaxOptions);
86
87
4.07k
    std::vector<std::string> command_line_container;
88
4.07k
    command_line_container.reserve(argc);
89
90
4.07k
    std::vector<const char*> argv;
91
4.07k
    argv.reserve(argc);
92
93
1.04M
    for (int i = 0; i < argc; i++)
94
1.03M
    {
95
1.03M
      command_line_container.push_back(
96
1.03M
        provider.ConsumeRandomLengthString(kMaxArgSize));
97
1.03M
      argv.push_back(command_line_container[i].c_str());
98
1.03M
    }
99
100
    // Parse command line;
101
4.07k
    auto result = options.parse(argc, argv.data());
102
4.07k
  } catch (...)
103
4.43k
  {
104
1.04k
  }
105
106
4.43k
  return 0;
107
4.43k
}