diff options
| author | nicole mazzuca <mazzucan@outlook.com> | 2020-04-17 18:16:20 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-17 18:16:20 -0700 |
| commit | 09af1e9b55fdb79ef5aa04de3f1710759b2de990 (patch) | |
| tree | fc151fb148667d5cf10bf3dcd8e26b5d04cc6d16 /toolsrc/src/vcpkg-fuzz/main.cpp | |
| parent | 556325a1f7b6049d91565257c00db2f0bf1eadc5 (diff) | |
| download | vcpkg-09af1e9b55fdb79ef5aa04de3f1710759b2de990.tar.gz vcpkg-09af1e9b55fdb79ef5aa04de3f1710759b2de990.zip | |
[vcpkg] Add initial JSON support (#10521)
* [vcpkg] Add initial JSON support
This adds a JSON parser, as well as the amount of unicode support
required for JSON parsing to work according to the specification. In the
future, I hope to rewrite our existing XML files into JSON.
Additionally, as a drive-by, we've added the following:
* add /wd4800 to pragmas.h -- this is a "performance warning", for when
you implicitly convert pointers or integers to bool, and shouldn't be
an issue for us.
* Switched Parse::ParserBase to read unicode (as utf-8), as opposed to
ASCII
* Building again under VCPKG_DEVELOPMENT_WARNINGS, yay!
Diffstat (limited to 'toolsrc/src/vcpkg-fuzz/main.cpp')
| -rw-r--r-- | toolsrc/src/vcpkg-fuzz/main.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/toolsrc/src/vcpkg-fuzz/main.cpp b/toolsrc/src/vcpkg-fuzz/main.cpp new file mode 100644 index 000000000..881577654 --- /dev/null +++ b/toolsrc/src/vcpkg-fuzz/main.cpp @@ -0,0 +1,144 @@ +#include <vcpkg/base/checks.h> +#include <vcpkg/base/json.h> +#include <vcpkg/base/stringview.h> +#include <vcpkg/base/system.print.h> + +#include <iostream> +#include <sstream> +#include <string.h> +#include <utility> + +using namespace vcpkg; + +namespace +{ + enum class FuzzKind + { + None, + Utf8Decoder, + JsonParser, + }; + + struct FuzzArgs + { + FuzzArgs(int argc, char** argv) + { + if (argc <= 1) + { + print_help_and_exit(); + } + + char** it = argv + 1; // skip the name of the program + char** last = argv + argc; + + for (; it != last; ++it) + { + auto arg = StringView(*it, strlen(*it)); + if (arg == "/?") + { + print_help_and_exit(); + } + + auto pr = split_arg(arg); + auto key = pr.first; + auto value = pr.second; + if (key == "h" || key == "help") + { + print_help_and_exit(); + } + + if (key == "kind") + { + if (value == "json") + { + kind = FuzzKind::JsonParser; + } + else if (value == "utf-8") + { + kind = FuzzKind::Utf8Decoder; + } + else + { + System::print2(System::Color::error, "Invalid kind: ", value, "\n"); + System::print2(System::Color::error, " Expected one of: utf-8, json\n\n"); + print_help_and_exit(true); + } + } + else + { + System::print2("Unknown option: ", key, "\n\n"); + print_help_and_exit(true); + } + } + } + + // returns {arg, ""} when there isn't an `=` + // skips preceding `-`s + std::pair<StringView, StringView> split_arg(StringView arg) + { + auto first = std::find_if(arg.begin(), arg.end(), [](char c) { return c != '-'; }); + auto division = std::find(first, arg.end(), '='); + if (division == arg.end()) { + return {StringView(first, arg.end()), StringView(arg.end(), arg.end())}; + } else { + return {StringView(first, division), StringView(division + 1, arg.end())}; + } + } + + [[noreturn]] void print_help_and_exit(bool invalid = false) + { + constexpr auto help = + R"( +Usage: vcpkg-fuzz <options> + +Accepts input on stdin. + +Options: + --kind=... One of {utf-8, json} +)"; + + auto color = invalid ? System::Color::error : System::Color::success; + + System::print2(color, help); + if (invalid) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + else + { + Checks::exit_success(VCPKG_LINE_INFO); + } + } + + FuzzKind kind; + }; + + std::string read_all_of_stdin() + { + std::stringstream ss; + ss << std::cin.rdbuf(); + return std::move(ss).str(); + } + +} + +int main(int argc, char** argv) +{ + auto args = FuzzArgs(argc, argv); + + if (args.kind == FuzzKind::None) + { + args.print_help_and_exit(true); + } + + auto text = read_all_of_stdin(); + auto res = Json::parse(text); + if (!res) + { + System::print2(System::Color::error, res.error()->format()); + } + else + { + System::print2(System::Color::success, "success!"); + } +} |
