Skip to content

Commit 7868518

Browse files
Google-Autofuzzbaylesj
authored andcommitted
Add a simple fuzz test for jsoncpp.
1 parent 629a727 commit 7868518

File tree

5 files changed

+81
-0
lines changed

5 files changed

+81
-0
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ datadiode <[email protected]>
3737
David Seifert <[email protected]>
3838
David West <[email protected]>
3939
40+
Devin Jeanpierre <[email protected]>
4041
Dmitry Marakasov <[email protected]>
4142
dominicpezzuto <[email protected]>
4243
Don Milham <[email protected]>

src/test_lib_json/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
add_executable( jsoncpp_test
44
jsontest.cpp
55
jsontest.h
6+
fuzz.cpp
7+
fuzz.h
68
main.cpp
79
)
810

src/test_lib_json/fuzz.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2007-2010 The JsonCpp Authors
2+
// Distributed under MIT license, or public domain if desired and
3+
// recognized in your jurisdiction.
4+
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5+
6+
#include "fuzz.h"
7+
8+
#include <bits/stdint-uintn.h>
9+
#include <json/config.h>
10+
#include <json/json.h>
11+
#include <memory>
12+
#include <stdint.h>
13+
#include <string>
14+
15+
namespace Json {
16+
class Exception;
17+
}
18+
19+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
20+
Json::CharReaderBuilder builder;
21+
22+
if (size < sizeof(uint32_t)) {
23+
return 0;
24+
}
25+
26+
uint32_t hash_settings = *(const uint32_t*)data;
27+
data += sizeof(uint32_t);
28+
29+
builder.settings_["failIfExtra"] = hash_settings & (1 << 0);
30+
builder.settings_["allowComments_"] = hash_settings & (1 << 1);
31+
builder.settings_["strictRoot_"] = hash_settings & (1 << 2);
32+
builder.settings_["allowDroppedNullPlaceholders_"] = hash_settings & (1 << 3);
33+
builder.settings_["allowNumericKeys_"] = hash_settings & (1 << 4);
34+
builder.settings_["allowSingleQuotes_"] = hash_settings & (1 << 5);
35+
builder.settings_["failIfExtra_"] = hash_settings & (1 << 6);
36+
builder.settings_["rejectDupKeys_"] = hash_settings & (1 << 7);
37+
builder.settings_["allowSpecialFloats_"] = hash_settings & (1 << 8);
38+
39+
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
40+
41+
Json::Value root;
42+
const char* data_str = reinterpret_cast<const char*>(data);
43+
try {
44+
reader->parse(data_str, data_str + size, &root, nullptr);
45+
} catch (Json::Exception const&) {
46+
}
47+
// Whether it succeeded or not doesn't matter.
48+
return 0;
49+
}

src/test_lib_json/fuzz.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2007-2010 The JsonCpp Authors
2+
// Distributed under MIT license, or public domain if desired and
3+
// recognized in your jurisdiction.
4+
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5+
6+
#ifndef FUZZ_H_INCLUDED
7+
#define FUZZ_H_INCLUDED
8+
9+
#include <stddef.h>
10+
#include <stdint.h>
11+
12+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
13+
14+
#endif // ifndef FUZZ_H_INCLUDED

src/test_lib_json/main.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#pragma warning(disable : 4996)
1111
#endif
1212

13+
#include "fuzz.h"
1314
#include "jsontest.h"
1415
#include <cmath>
1516
#include <cstring>
@@ -2555,6 +2556,18 @@ JSONTEST_FIXTURE(RValueTest, moveConstruction) {
25552556
JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type());
25562557
}
25572558

2559+
struct FuzzTest : JsonTest::TestCase {};
2560+
2561+
// Build and run the fuzz test without any fuzzer, so that it's guaranteed not
2562+
// go out of date, even if it's never run as an actual fuzz test.
2563+
JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) {
2564+
const std::string example = "{}";
2565+
JSONTEST_ASSERT_EQUAL(
2566+
0,
2567+
LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t*>(example.c_str()),
2568+
example.size()));
2569+
}
2570+
25582571
int main(int argc, const char* argv[]) {
25592572
JsonTest::Runner runner;
25602573
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
@@ -2635,6 +2648,8 @@ int main(int argc, const char* argv[]) {
26352648

26362649
JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction);
26372650

2651+
JSONTEST_REGISTER_FIXTURE(runner, FuzzTest, fuzzDoesntCrash);
2652+
26382653
return runner.runCommandLine(argc, argv);
26392654
}
26402655

0 commit comments

Comments
 (0)