diff options
Diffstat (limited to 'src/boost/libs/json/fuzzing/fuzz_parser.cpp')
-rw-r--r-- | src/boost/libs/json/fuzzing/fuzz_parser.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/boost/libs/json/fuzzing/fuzz_parser.cpp b/src/boost/libs/json/fuzzing/fuzz_parser.cpp new file mode 100644 index 000000000..d6598dbde --- /dev/null +++ b/src/boost/libs/json/fuzzing/fuzz_parser.cpp @@ -0,0 +1,139 @@ +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2020 Paul Dreik (github@pauldreik.se) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/json +// + +#include <boost/json/parse_options.hpp> +#include <boost/json/serialize.hpp> +#include <boost/json/stream_parser.hpp> +#include <boost/json/monotonic_resource.hpp> +#include <boost/json/null_resource.hpp> +#include <boost/json/static_resource.hpp> +#include <memory> + +using namespace boost::json; + +struct FuzzHelper { + parse_options opt; + string_view jsontext; + std::size_t memlimit1; + std::size_t memlimit2; + bool res; + void run(stream_parser& p) { + error_code ec; + + // Write the first part of the buffer + p.write( jsontext, ec); + + if(! ec) + p.finish( ec ); + + // Take ownership of the resulting value. + if(! ec) + { + value jv = p.release(); + res=serialize(jv).size()==42; + } else + res=false; + } + + // easy case - everything default + void useDefault() { + stream_parser p(storage_ptr{}, opt); + run(p); + } + + void useMonotonic() { + monotonic_resource mr; + stream_parser p(storage_ptr{}, opt); + p.reset( &mr ); + + run(p); + } + + void useLocalBuffer() { + std::unique_ptr<unsigned char[]> temp(new unsigned char[memlimit1]); + stream_parser p( + storage_ptr(), + opt, + temp.get(), + memlimit1); + run(p); + } + + void useDynLess() { + // this is on the heap because the size is chosen dynamically + std::unique_ptr<unsigned char[]> temp(new unsigned char[memlimit1]); + stream_parser p(get_null_resource(), + opt, + temp.get(), + memlimit1); + + // this is on the heap because the size is chosen dynamically + std::unique_ptr<unsigned char[]> buf(new unsigned char[memlimit2]); + static_resource mr2( buf.get(), memlimit2 ); + p.reset( &mr2 ); + + run(p); + } + +}; + + +extern "C" +int +LLVMFuzzerTestOneInput( + const uint8_t* data, size_t size) +{ + if(size<=5) + return 0; + + FuzzHelper fh; + + // set parse options + fh.opt.allow_comments=!!(data[0]&0x1); + fh.opt.allow_trailing_commas=!!(data[0]&0x2); + fh.opt.allow_invalid_utf8=!!(data[0]&0x4); + fh.opt.max_depth= (data[0]>>3); + + // select memory strategy to use + const int strategy=data[1] & 0x3; + + // memory limits + fh.memlimit1=data[2]*256+data[3]; + fh.memlimit2=data[4]*256+data[5]; + + data+=6; + size-=6; + + //set the json string to parse + fh.jsontext=string_view{ + reinterpret_cast<const char*>( + data), size}; + try + { + switch(strategy) { + case 0: + fh.useDefault(); + break; + case 1: + fh.useDefault(); + break; + case 2: + fh.useLocalBuffer(); + break; + case 3: + fh.useDynLess(); + break; + } + } + catch(...) + { + } + return 0; +} + |