#include #include #include constexpr int kMaxOptions = 1024; constexpr int kMaxArgSize = 1024; enum class ParseableTypes { kInt, kString, kVectorString, kFloat, kDouble, // Marker for fuzzer. kMaxValue, }; template void add_fuzzed_option(cxxopts::Options* options, FuzzedDataProvider* provider) { assert(options); assert(provider); options->add_options()(provider->ConsumeRandomLengthString(kMaxArgSize), provider->ConsumeRandomLengthString(kMaxArgSize), cxxopts::value()); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { try { FuzzedDataProvider provider(data, size); // Randomly generate a usage string. cxxopts::Options options(provider.ConsumeRandomLengthString(kMaxArgSize), provider.ConsumeRandomLengthString(kMaxArgSize)); // Randomly generate a set of flags configurations. for (int i = 0; i < provider.ConsumeIntegralInRange(0, kMaxOptions); i++) { switch (provider.ConsumeEnum()) { case ParseableTypes::kInt: add_fuzzed_option(&options, &provider); break; case ParseableTypes::kString: add_fuzzed_option(&options, &provider); break; case ParseableTypes::kVectorString: add_fuzzed_option>(&options, &provider); break; case ParseableTypes::kFloat: add_fuzzed_option(&options, &provider); break; case ParseableTypes::kDouble: add_fuzzed_option(&options, &provider); break; default: break; } } // Sometimes allow unrecognised options. if (provider.ConsumeBool()) { options.allow_unrecognised_options(); } // Sometimes allow trailing positional arguments. if (provider.ConsumeBool()) { std::string positional_option_name = provider.ConsumeRandomLengthString(kMaxArgSize); options.add_options()(positional_option_name, provider.ConsumeRandomLengthString(kMaxArgSize), cxxopts::value>()); options.parse_positional({positional_option_name}); } // Build command line input. const int argc = provider.ConsumeIntegralInRange(1, kMaxOptions); std::vector command_line_container; command_line_container.reserve(argc); std::vector argv; argv.reserve(argc); for (int i = 0; i < argc; i++) { command_line_container.push_back( provider.ConsumeRandomLengthString(kMaxArgSize)); argv.push_back(command_line_container[i].c_str()); } // Parse command line; auto result = options.parse(argc, argv.data()); } catch (...) { } return 0; }