/src/jq/tests/jq_fuzz_execute.cpp
Line | Count | Source |
1 | | #include <fuzzer/FuzzedDataProvider.h> |
2 | | #include <string> |
3 | | |
4 | | #include "jq.h" |
5 | | #include "jv.h" |
6 | | #include "oniguruma.h" |
7 | | |
8 | 2 | extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { |
9 | 2 | onig_set_parse_depth_limit(1024); |
10 | 2 | return 0; |
11 | 2 | } |
12 | | |
13 | | // Fuzzer inspired by /src/jq_test.c |
14 | | // The goal is to have the fuzzer execute the functions: |
15 | | // jq_compile -> jv_parse -> jq_next. |
16 | 27.5k | extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { |
17 | 27.5k | FuzzedDataProvider fdp(data, size); |
18 | 27.5k | std::string prog_payload = fdp.ConsumeRandomLengthString(); |
19 | 27.5k | std::string parse_payload1 = fdp.ConsumeRandomLengthString(); |
20 | 27.5k | std::string parse_payload2 = fdp.ConsumeRandomLengthString(); |
21 | | |
22 | 27.5k | jq_state *jq = NULL; |
23 | 27.5k | jq = jq_init(); |
24 | 27.5k | if (jq != NULL) { |
25 | 27.5k | jq_set_attr(jq, jv_string("JQ_ORIGIN"), jv_string("/tmp/")); |
26 | | |
27 | 27.5k | if (jq_compile(jq, prog_payload.c_str())) { |
28 | | // Process to jv_parse and then jv_next |
29 | 23.9k | jv input = jv_parse(parse_payload1.c_str()); |
30 | 23.9k | if (jv_is_valid(input)) { |
31 | 20.7k | jq_start(jq, input, 0); |
32 | 20.7k | jv next = jv_parse(parse_payload2.c_str()); |
33 | 20.7k | if (jv_is_valid(next)) { |
34 | 20.1k | jv actual = jq_next(jq); |
35 | 20.1k | jv_free(actual); |
36 | 20.1k | } |
37 | 20.7k | jv_free(next); |
38 | 20.7k | } else { |
39 | | // Only free if input is invalid as otherwise jq_teardown |
40 | | // frees it. |
41 | 3.19k | jv_free(input); |
42 | 3.19k | } |
43 | 23.9k | } |
44 | 27.5k | } |
45 | 27.5k | jq_teardown(&jq); |
46 | | |
47 | 27.5k | return 0; |
48 | 27.5k | } |