Skip to content

Commit 94c082c

Browse files
committed
Added fuzzing app
1 parent 424d734 commit 94c082c

File tree

7 files changed

+79
-1
lines changed

7 files changed

+79
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.sublime-workspace
22
build*/
33
.sublime-tests/
4+
fuzzing/output

CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ else()
1818
endif()
1919

2020
# Components (library is always built).
21-
set(JSONEXPR_APP ON CACHE BOOL "Build command line application.")
21+
set(JSONEXPR_APP ON CACHE BOOL "Build command line application.")
2222
set(JSONEXPR_TEST OFF CACHE BOOL "Build tests.")
23+
set(JSONEXPR_FUZZ OFF CACHE BOOL "Build fuzzing application.")
2324

2425
# Dependencies.
2526
set(JSONEXPR_USE_SYSTEM_JSON OFF CACHE BOOL "Use a pre-installed version of nlohmann::json. Else, download.")
@@ -40,3 +41,7 @@ if (JSONEXPR_TEST)
4041
enable_testing()
4142
add_subdirectory(tests)
4243
endif()
44+
45+
if (JSONEXPR_FUZZ)
46+
add_subdirectory(fuzzing/runner)
47+
endif()

fuzzing/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# How to run fuzzing
2+
3+
## Install AFL++
4+
5+
```
6+
docker pull aflplusplus/aflplusplus:latest
7+
```
8+
9+
## Build with fuzzing instrumentation
10+
11+
From the root of the repo:
12+
```
13+
docker run -ti --mount type=tmpfs,destination=/ramdisk --mount type=bind,source=.,destination=/src -e AFL_TMPDIR=/ramdisk -e AFL_USE_ASAN=1 aflplusplus/aflplusplus
14+
cd /src
15+
mkdir build_fuzzing
16+
cd build_fuzzing
17+
cmake .. -DCMAKE_CXX_COMPILER=afl-clang-fast++ -DCMAKE_BUILD_TYPE=RelWithDebInfo
18+
make -j12
19+
```
20+
21+
## Start fuzzing
22+
23+
Within the same container as above:
24+
```
25+
afl-fuzz -i fuzzing/input -o fuzzing/output build_fuzzing/fuzzing/runner/jsonexpr-fuzzing-runner @@
26+
```

fuzzing/input/fuzz.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cat.colors[(bee.legs - cat.legs)/2]

fuzzing/runner/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
3+
project(jsonexpr-fuzzing-runner LANGUAGES CXX)
4+
5+
add_executable(jsonexpr-fuzzing-runner
6+
${PROJECT_SOURCE_DIR}/src/main.cpp)
7+
8+
target_link_libraries(jsonexpr-fuzzing-runner PUBLIC jsonexpr::libjsonexpr)
9+

fuzzing/runner/src/main.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "jsonexpr/jsonexpr.hpp"
2+
3+
#include <fstream>
4+
#include <iostream>
5+
6+
__AFL_FUZZ_INIT();
7+
8+
int main() {
9+
jsonexpr::variable_registry vars;
10+
jsonexpr::function_registry funcs = jsonexpr::default_functions();
11+
12+
#ifdef __AFL_HAVE_MANUAL_CONTROL
13+
__AFL_INIT();
14+
#endif
15+
16+
// must be after __AFL_INIT and before __AFL_LOOP!
17+
unsigned char* buf = __AFL_FUZZ_TESTCASE_BUF;
18+
19+
while (__AFL_LOOP(10000)) {
20+
// Don't use the macro directly in a call!
21+
const int len = __AFL_FUZZ_TESTCASE_LEN;
22+
const char* expr_chars = reinterpret_cast<char*>(buf);
23+
24+
const auto expression = std::string_view{expr_chars, expr_chars + len};
25+
const auto result = jsonexpr::evaluate(expression, vars, funcs);
26+
if (!result.has_value()) {
27+
jsonexpr::format_error(expression, result.error());
28+
}
29+
}
30+
31+
return 0;
32+
}

jsonexpr.sublime-project

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
[
44
{
55
"path": ".",
6+
"folder_exclude_patterns":
7+
[
8+
"fuzzing/output"
9+
]
610
}
711
],
812
"settings":

0 commit comments

Comments
 (0)