Skip to content

Commit ccb3339

Browse files
committed
direct parsing fuzzing test
1 parent 27c40ee commit ccb3339

File tree

7 files changed

+102
-3
lines changed

7 files changed

+102
-3
lines changed

fuzzing/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ corpus.tar
66
fuzzer_basic_parser
77
fuzzer_parse
88
fuzzer_parser
9+
fuzzer_direct_parse
910
out*/
1011
fuzz-*.log
1112

fuzzing/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ source_group("" FILES
1111
fuzz_basic_parser.cpp
1212
fuzz_parse.cpp
1313
fuzz_parser.cpp
14+
fuzz_direct_parse.cpp
1415
)
1516

1617
# The fuzzers are built as libraries, to make
@@ -33,3 +34,6 @@ add_library(fuzzerlib_parser fuzz_parser.cpp)
3334
set_property(TARGET fuzzerlib_parser PROPERTY FOLDER "fuzzing")
3435
target_link_libraries(fuzzerlib_parser PRIVATE Boost::json)
3536

37+
add_library(fuzzerlib_direct_parse fuzz_direct_parse.cpp)
38+
set_property(TARGET fuzzerlib_direct_parse PROPERTY FOLDER "fuzzing")
39+
target_link_libraries(fuzzerlib_direct_parse PRIVATE Boost::json)

fuzzing/Jamfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ explicit old-corpus ;
5959
local initial-corpus = [ glob-tree-ex ../test : *.json ] ;
6060

6161

62-
local variants = basic_parser parse parser ;
63-
for local variant in basic_parser parse parser
62+
local variants = basic_parser parse parser direct_parse ;
63+
for local variant in basic_parser parse parser direct_parse
6464
{
6565
local $(variant)-runs ;
6666
local fuzzer = fuzzer_$(variant) ;

fuzzing/fuzz.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ JOBS=
4444
# set a timelimit (you may want to adjust this if you run locally)
4545
MAXTIME="-max_total_time=30"
4646

47-
variants="basic_parser parse parser"
47+
variants="basic_parser parse parser direct_parse"
4848

4949
for variant in $variants; do
5050

fuzzing/fuzz_direct_parse.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) 2024 Mikhail Khachayants ([email protected])
2+
//
3+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
//
6+
// Official repository: https://github.com/boostorg/json
7+
//
8+
9+
#include <boost/json/parse_into.hpp>
10+
#include <boost/describe.hpp>
11+
#include <map>
12+
13+
#ifndef BOOST_NO_CXX17_HDR_VARIANT
14+
# include <variant>
15+
# define IF_CXX17_HDR_VARIANT(...) __VA_ARGS__
16+
#else
17+
# define IF_CXX17_HDR_VARIANT(...)
18+
#endif // BOOST_NO_CXX17_HDR_VARIANT
19+
20+
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
21+
# include <optional>
22+
# define IF_CXX17_HDR_OPTIONAL(...) __VA_ARGS__
23+
#else
24+
# define IF_CXX17_HDR_OPTIONAL(...)
25+
#endif // BOOST_NO_CXX17_HDR_OPTIONAL
26+
27+
using namespace boost::json;
28+
29+
struct Object
30+
{
31+
bool b;
32+
float f;
33+
double d;
34+
std::int64_t i64;
35+
std::uint64_t u64;
36+
std::string s;
37+
std::vector<bool> v1;
38+
std::vector<std::int64_t> v2;
39+
std::vector<std::uint64_t> v3;
40+
std::array<bool, 3> a1;
41+
std::array<std::int64_t, 3> a2;
42+
std::array<std::uint64_t, 3> a3;
43+
std::map<std::string, std::int64_t> m1;
44+
std::map<std::string, std::string> m2;
45+
std::map<std::string, double> m3;
46+
std::tuple<bool, std::uint64_t, std::int64_t, double, std::string> t1;
47+
std::tuple<std::array<std::string, 3>, std::array<double, 3>, std::nullptr_t> t2;
48+
std::tuple<std::vector<std::string>, std::vector<double>> t3;
49+
50+
#ifndef BOOST_NO_CXX17_HDR_VARIANT
51+
std::variant<bool, std::uint64_t, std::int64_t, double, std::string> v;
52+
#endif // BOOST_NO_CXX17_HDR_VARIANT
53+
54+
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
55+
std::optional<bool> ob;
56+
std::optional<std::int64_t> oi;
57+
std::optional<std::uint64_t> ou;
58+
std::optional<double> od;
59+
std::optional<std::string> os;
60+
#endif // BOOST_NO_CXX17_HDR_OPTIONAL
61+
};
62+
63+
BOOST_DESCRIBE_STRUCT(Object, (),
64+
(b, i64, u64, f, d, s, v1, v2, v3, a1, a2, a3, m1, m2, m3, t1, t2, t3,
65+
IF_CXX17_HDR_OPTIONAL(ob, oi, ou, od, os), IF_CXX17_HDR_OPTIONAL(v)))
66+
67+
bool
68+
fuzz_direct_parse(string_view sv)
69+
{
70+
Object object;
71+
boost::system::error_code ec;
72+
parse_into(object, sv, ec);
73+
return !ec;
74+
}
75+
76+
extern "C"
77+
int
78+
LLVMFuzzerTestOneInput(
79+
const uint8_t* data, size_t size)
80+
{
81+
try
82+
{
83+
string_view sv{reinterpret_cast<
84+
const char*>(data), size};
85+
fuzz_direct_parse(sv);
86+
}
87+
catch(...)
88+
{
89+
}
90+
return 0;
91+
}
92+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"a2":[977,775500052916,9216,77552916,9216]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"t1":[]}

0 commit comments

Comments
 (0)