Skip to content

Commit 3f88a33

Browse files
committed
direct parsing fuzzing test
1 parent 502ac79 commit 3f88a33

File tree

10 files changed

+142
-3
lines changed

10 files changed

+142
-3
lines changed

.github/workflows/run_fuzzer.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ jobs:
6060
buildtype: 'boost'
6161
path: 'head'
6262
toolset: clang-18
63+
cxxstd: 17
6364
targets: libs/json/fuzzing//run
6465
- name: Pack the corpus
6566
working-directory: boost-root/libs/json/fuzzing/

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: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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/variant2/variant.hpp>
11+
#include <boost/describe.hpp>
12+
#include <map>
13+
14+
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
15+
# include <optional>
16+
# define IF_CXX17_HDR_OPTIONAL(...) __VA_ARGS__
17+
#else
18+
# define IF_CXX17_HDR_OPTIONAL(...)
19+
#endif // BOOST_NO_CXX17_HDR_OPTIONAL
20+
21+
using namespace boost::json;
22+
23+
struct Object
24+
{
25+
bool b;
26+
float f;
27+
double d;
28+
std::int64_t i64;
29+
std::uint64_t u64;
30+
std::string s;
31+
std::vector<bool> v1;
32+
std::vector<std::int64_t> v2;
33+
std::vector<std::uint64_t> v3;
34+
std::array<bool, 3> a1;
35+
std::array<std::int64_t, 3> a2;
36+
std::array<std::uint64_t, 3> a3;
37+
std::map<std::string, std::int64_t> m1;
38+
std::map<std::string, std::string> m2;
39+
std::map<std::string, double> m3;
40+
std::tuple<bool, std::uint64_t, std::int64_t, double, std::string> t1;
41+
std::tuple<std::array<std::string, 3>, std::array<double, 3>, std::nullptr_t> t2;
42+
std::tuple<std::vector<std::string>, std::vector<double>> t3;
43+
boost::variant2::variant<bool, std::uint64_t, std::int64_t, double, std::string> v;
44+
45+
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
46+
std::optional<bool> ob;
47+
std::optional<std::int64_t> oi;
48+
std::optional<std::uint64_t> ou;
49+
std::optional<double> od;
50+
std::optional<std::string> os;
51+
#endif // BOOST_NO_CXX17_HDR_OPTIONAL
52+
};
53+
54+
BOOST_DESCRIBE_STRUCT(Object, (),
55+
(b, i64, u64, f, d, s, v1, v2, v3, a1, a2, a3, m1, m2, m3, t1, t2, t3, v,
56+
IF_CXX17_HDR_OPTIONAL(ob, oi, ou, od, os)))
57+
58+
59+
bool
60+
fuzz_direct_parse(string_view sv)
61+
{
62+
Object object;
63+
boost::system::error_code ec;
64+
parse_into(object, sv, ec);
65+
return !ec;
66+
}
67+
68+
extern "C"
69+
int
70+
LLVMFuzzerTestOneInput(
71+
const uint8_t* data, size_t size)
72+
{
73+
try
74+
{
75+
string_view sv{reinterpret_cast<
76+
const char*>(data), size};
77+
fuzz_direct_parse(sv);
78+
}
79+
catch(...)
80+
{
81+
}
82+
return 0;
83+
}
84+
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":[]}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"b": true,
3+
"i64": -123,
4+
"u64": 123,
5+
"f": 123.45,
6+
"d": 0.9832747263462,
7+
"s": "text",
8+
"v1": [true, false],
9+
"v2": [-12, 89],
10+
"v3": [1000, 0],
11+
"a1": [true, false, true],
12+
"a2": [-1, 2, 3],
13+
"a3": [1, 2, 3],
14+
"m1": {"k": 42},
15+
"m2": {"k": "v"},
16+
"m3": {"k": 0.42},
17+
"t1": [true, 1, 2, 1.23, "s"],
18+
"t2": [["a", "b", "c"], [1.0, 0.1, 2.2], null],
19+
"t3": [[], []],
20+
"v": "text"
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"b": true,
3+
"i64": -123,
4+
"u64": 123,
5+
"f": 123.45,
6+
"d": 0.9832747263462,
7+
"s": "text",
8+
"v1": [true, false],
9+
"v2": [-12, 89],
10+
"v3": [1000, 0],
11+
"a1": [true, false, true],
12+
"a2": [-1, 2, 3],
13+
"a3": [1, 2, 3],
14+
"m1": {"k": 42},
15+
"m2": {"k": "v"},
16+
"m3": {"k": 0.42},
17+
"t1": [true, 1, 2, 1.23, "s"],
18+
"t2": [["a", "b", "c"], [1.0, 0.1, 2.2], null],
19+
"t3": [[], []],
20+
"ob": null,
21+
"oi": 123,
22+
"ou": 456,
23+
"od": 1.1,
24+
"os": null,
25+
"v": "text"
26+
}

0 commit comments

Comments
 (0)