// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include #include #include "flatbuffers/idl.h" #include "test_init.h" static constexpr uint8_t flags_strict_json = 0x01; static constexpr uint8_t flags_skip_unexpected_fields_in_json = 0x02; static constexpr uint8_t flags_allow_non_utf8 = 0x04; // static constexpr uint8_t flags_flag_3 = 0x08; // static constexpr uint8_t flags_flag_4 = 0x10; // static constexpr uint8_t flags_flag_5 = 0x20; // static constexpr uint8_t flags_flag_6 = 0x40; // static constexpr uint8_t flags_flag_7 = 0x80; // Utility for test run. OneTimeTestInit OneTimeTestInit::one_time_init_; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // Reserve one byte for Parser flags and one byte for repetition counter. if (size < 3) return 0; const uint8_t flags = data[0]; // normalize to ascii alphabet const int extra_rep_number = data[1] >= '0' ? (data[1] - '0') : 0; data += 2; size -= 2; // bypass const std::string original(reinterpret_cast(data), size); auto input = std::string(original.c_str()); // until '\0' if (input.empty()) return 0; flatbuffers::IDLOptions opts; opts.strict_json = (flags & flags_strict_json); opts.skip_unexpected_fields_in_json = (flags & flags_skip_unexpected_fields_in_json); opts.allow_non_utf8 = (flags & flags_allow_non_utf8); flatbuffers::Parser parser(opts); // Guarantee 0-termination in the input. auto parse_input = input.c_str(); // The fuzzer can adjust the number repetition if a side-effects have found. // Each test should pass at least two times to ensure that the parser doesn't // have any hidden-states or locale-depended effects. for (auto cnt = 0; cnt < (extra_rep_number + 2); cnt++) { // Each even run (0,2,4..) will test locale independed code. auto use_locale = !!OneTimeTestInit::test_locale() && (0 == (cnt % 2)); // Set new locale. if (use_locale) { FLATBUFFERS_ASSERT(setlocale(LC_ALL, OneTimeTestInit::test_locale())); } // Check Parser. parser.Parse(parse_input); // Restore locale. if (use_locale) { FLATBUFFERS_ASSERT(setlocale(LC_ALL, "C")); } } return 0; }