Skip to content

Commit

Permalink
tests: add new fuzzer
Browse files Browse the repository at this point in the history
Signed-off-by: David Korczynski <david@adalogics.com>
  • Loading branch information
DavidKorczynski authored and emanuele6 committed Dec 7, 2023
1 parent 20a403e commit 5029328
Showing 1 changed file with 297 additions and 0 deletions.
297 changes: 297 additions & 0 deletions tests/jq_fuzz_fixed.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
#include <fuzzer/FuzzedDataProvider.h>
#include <string>

#include "jq.h"
#include "jv.h"


const char *jq_progs[] = {
". / \", \"",
".[]",
"$ENV.PAGER",
".[0]",
". < 0.12345678901234567890123456788",
".[] == 1",
".[] | (1 / .)?",
"10 / . * 3",
"[1,2,empty,3]",
"1, empty, 2",
"[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]",
".[-2:]",
".[-2]",
".[2]",
"[ .[] | . * 2]",
".[2:4]",
"(. + 2) * 5",
".[:3]",
".[4,2]",
"42 and \"a string\"",
"4 - .a",
". < 5",
".. | .a?",
"[.[] | .a?]",
".a + 1",
"{a: 1} + {b: 2} + {c: 3} + {a: 42}",
".a + .b",
".a = .b",
".a |= .b",
"add",
"all",
".a + null",
"any",
".[] as [$a, $b] | {a: $a, b: $b}",
". as [$a, $b, {c: $c}] | $a + $b + $c",
".[] as {$a, $b, c: {$d}} ?// {$a, $b, c: [{$e}]} | {$a, $b, $d, $e}",
".[] as {$a, $b, c: {$d, $e}} ?// {$a, $b, c: [{$d, $e}]} | {$a, $b, "
"$d, $e}",
".[] as [$a] ?// [$b] | if $a != null then error(\"err: \($a)\") else "
"{$a,$b} end",
". as $big | [$big, $big + 1] | map(. > "
"10000000000000000000000000000000)",
". as $dot|fromstream($dot|tostream)|.==$dot",
". as $i|[(.*2|. as $i| $i), $i]",
"ascii_upcase",
".bar as $x | .foo | . + $x",
"@base64",
"@base64d",
". == {\"b\": {\"d\": (4 + 1e-20), \"c\": 3}, \"a\":1}",
"bsearch(0)",
"bsearch(4) as $ix | if $ix < 0 then .[-(1+$ix)] = 4 else . end",
"capture(\"(?<a>[a-z]+)-(?<n>[0-9]+)\")",
"capture(\"(?<a>[a-z]+)-(?<n>[0-9]+)\")",
"combinations",
"combinations(2)",
"contains(\"bar\")",
"contains([\"baz\", \"bar\"])",
"contains([\"bazzzzz\", \"bar\"])",
"contains({foo: 12, bar: [{barp: 15}]})",
"def addvalue(f): f as $x | map(. + $x); addvalue(.[0])",
"def addvalue(f): . + [f]; map(addvalue(.[0]))",
"def while(cond; update): def _while: if cond then ., (update | "
"_while) else empty end; _while; [while(.<100; .*2)]",
"del(.[1, 2])",
"del(.foo)",
"delpaths([[\"a\",\"b\"]])",
"empty // 42",
"[.[]|endswith(\"foo\")]",
"env.PAGER",
"explode",
". == false",
"(false, null, 1) // 42",
"(false, null, 1) | . // 42",
"flatten",
"flatten(1)",
"floor",
".[\"foo\"]",
".[\"foo\"]?",
".foo",
".foo?",
".foo[]",
"[.foo?]",
".foo += 1",
".foo // 42",
".foo, .bar",
"foreach .[] as $item (0; . + $item)",
"foreach .[] as $item (0; . + $item; [$item, . * 2])",
"foreach .[] as $item (0; . + 1; {index: ., $item})",
"fromdate",
"from_entries",
"fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]))",
"getpath([\"a\",\"b\"])",
"[getpath([\"a\",\"b\"], [\"a\",\"c\"])]",
"group_by(.foo)",
"[.[] | gsub(\", \"; \":\")]",
"gsub(\"$\"; \"a\"; \"g\")",
"gsub(\"^\"; \"a\")",
"[gsub(\"(?<a>.)\"; \"\(.a|ascii_upcase)\", \"\(.a|ascii_downcase)\", "
"\"c\")]",
"gsub(\"^.*?a\"; \"b\")",
"gsub(\"^.*a\"; \"b\")",
"gsub(\"a\";\"b\")",
"gsub(\"\"; \"a\"; \"g\")",
"gsub(\"\"; \"a\"; \"g\")",
"gsub(\"[^a-z]*(?<x>[a-z]*)\"; \"Z\(.x)\")",
"gsub(\"\\b(?<x>.)\"; \"\(.x|ascii_downcase)\")",
"gsub(\"(?<d>\\d)\"; \":\(.d);\")",
"gsub(\"^\"; \"\"; \"g\")",
"[gsub(\"p\"; \"a\", \"b\")]",
"gsub(\"(?=u)\"; \"u\")",
"gsub(\"(.*)\"; \"\"; \"x\")",
"gsub(\"(?<x>.)[^a]*\"; \"+\(.x)-\")",
"gsub(\"(?<x>.)(?<y>[0-9])\"; \"\(.x|ascii_downcase)\(.y)\")",
"@html",
"if . == 0 then \"zero\" elif . == 1 then \"one\" else \"many\" "
"end",
"implode",
"index(\", \")",
"index(1)",
"index([1,2])",
"indices(\", \")",
"indices(1)",
"indices([1,2])",
".[] | (infinite * .) < 0",
"infinite, nan | type",
".[] | in({\"foo\": 42})",
"inside({\"foo\": 12, \"bar\":[1,2,{\"barp\":12, \"blip\":13}]})",
"inside({\"foo\": 12, \"bar\":[1,2,{\"barp\":12, \"blip\":13}]})",
"inside(\"foobar\")",
"inside([\"foobar\", \"foobaz\", \"blarp\"])",
"inside([\"foobar\", \"foobaz\", \"blarp\"])",
"isempty(.[])",
"isempty(.[])",
"isempty(empty)",
"join(\" \")",
"join(\", \")",
"keys",
"keys",
".[] | length",
"[limit(3;.[])]",
"[.[]|ltrimstr(\"foo\")]",
"map(., .)",
"map(.+1)",
"map([., . == 1]) | tojson",
"map(abs)",
"map(has(2))",
"map(has(\"foo\"))",
"map(in([0,1]))",
"map(select(. >= 2))",
"map(type)",
"map_values(.+1)",
"map_values(. // empty)",
"match(\"(abc)+\"; \"g\")",
"[match(\"a\"; \"gi\")]",
"[match(\".+?\\b\")]",
"[match([\"(bar)\"])]",
"match(\"foo\")",
"[match([\"foo (?<bar123>bar)? foo\", \"ig\"])]",
"match(\"foo (?<bar123>bar)? foo\"; \"ig\")",
"match([\"foo\", \"ig\"])",
"[match(\"\"; \"g\")]",
"[ match(\".\"; \"g\")] | length",
"[match(\"( )*\"; \"gn\")]",
"max_by(.foo)",
"min",
".[] | .name",
".[]|numbers",
"[path(..)]",
"path(.a[0].b)",
"[paths]",
"[paths(type == \"number\")]",
"pick(.[2], .[0], .[0])",
"pick(.a, .b.c, .x)",
"[range(0; 10; -1)]",
"[range(0; 10; 3)]",
"[range(0; -5; -1)]",
"[range(2; 4)]",
"range(2; 4)",
"[range(4)]",
"[range(.)]|[first, last, nth(5)]",
"recurse",
"recurse(. * .; . < 20)",
"recurse(.foo[])",
"reduce .[] as [$i,$j] (0; . + $i * $j)",
"reduce .[] as $item (0; . + $item)",
"reduce .[] as {$x,$y} (null; .x += $x | .y += [$y])",
"[repeat(.*2, error)?]",
"reverse",
"rindex(\", \")",
"rindex(1)",
"rindex([1,2])",
"[.[]|rtrimstr(\"foo\")]",
"[.[] | scan(\", \")]",
"[.[] | scan(\"b+\"; \"i\")]",
"scan(\"c\")",
".[] | select(.id == \"second\")",
"(..|select(type==\"boolean\")) |= if . then 1 else 0 end",
"setpath([0,\"a\"]; 1)",
"setpath([\"a\",\"b\"]; 1)",
"setpath([\"a\",\"b\"]; 1)",
"@sh \"echo \(.)\"",
"sort",
"sort_by(.foo)",
"sort_by(.foo, .bar)",
"split(\", *\"; null)",
"splits(\", *\")",
"sqrt",
"[.[]|startswith(\"foo\")]",
"strptime(\"%Y-%m-%dT%H:%M:%SZ\")",
"strptime(\"%Y-%m-%dT%H:%M:%SZ\")|mktime",
"[sub(\"(?<a>.)\"; \"\(.a|ascii_upcase)\", \"\(.a|ascii_downcase)\")]",
"[sub(\"(?<a>.)\"; \"\(.a|ascii_upcase)\", \"\(.a|ascii_downcase)\", "
"\"c\")]",
"[sub(\"a\"; \"b\", \"c\")]",
"sub(\"[^a-z]*(?<x>[a-z]+)\"; \"Z\(.x)\"; \"g\")",
"[.[]|[[sub(\", *\";\":\")], [gsub(\", *\";\":\")], [scan(\", *\")]]]",
"[.[]|[[sub(\", +\";\":\")], [gsub(\", +\";\":\")], [scan(\", +\")]]]",
"sub(\"^(?<head>.)\"; \"Head=\(.head) Tail=\")",
"[test(\"ā\")]",
".[] | test(\"a b c # spaces are ignored\"; \"ix\")",
"test(\"foo\")",
"to_entries",
"[., tojson]",
"[.[]|tojson]",
"[.[]|tojson|fromjson]",
".[] | tonumber",
"[.[] | tonumber?]",
".[] | tostring",
"[.[]|tostring]",
"transpose",
"[true, false | not]",
"(true, false) or false",
"(true, true) and (true, false)",
"truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]])",
"[.[]|try .a]",
"unique",
"unique_by(.foo)",
"unique_by(length)",
".user, .projects[]",
"[.user, .projects[]]",
"{(.user): .titles}",
"{user, title: .titles[]}",
"utf8bytelength",
"walk(if type == \"array\" then sort else . end)",
"walk( if type == \"object\" then with_entries( .key |= sub( \"^_+\"; "
"\"\") ) else . end )",
"[while(.<100; .*2)]",
"with_entries(.key |= \"KEY_\" + .)",
". - [\"xml\", \"yaml\"]",
};

// Fuzzer inspired by /src/jq_test.c
// The goal is to have the fuzzer execute the functions:
// jq_compile -> jv_parse -> jq_next.
extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
FuzzedDataProvider fdp(data, size);
std::string parse_payload1 = fdp.ConsumeRandomLengthString();
std::string parse_payload2 = fdp.ConsumeRandomLengthString();

int idx = fdp.ConsumeIntegralInRange<int>(
0, (sizeof(jq_progs) / sizeof(char *)) - 1);

jq_state *jq = NULL;
jq = jq_init();
if (jq != NULL) {
jq_set_attr(jq, jv_string("JQ_ORIGIN"), jv_string("/tmp/"));

if (jq_compile(jq, jq_progs[idx])) {
// Process to jv_parse and then jv_next
jv input = jv_parse(parse_payload1.c_str());
if (jv_is_valid(input)) {
jq_start(jq, input, 0);
jv next = jv_parse(parse_payload2.c_str());
if (jv_is_valid(next)) {
jv actual = jq_next(jq);
jv_free(actual);
}
jv_free(next);
} else {
// Only free if input is invalid as otherwise jq_teardown
// frees it.
jv_free(input);
}
}
}
jq_teardown(&jq);

return 0;
}

0 comments on commit 5029328

Please sign in to comment.