76 lines
2.1 KiB
Bash
Executable file
76 lines
2.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# shellcheck disable=SC2086
|
|
|
|
set -e
|
|
|
|
if [[ $(uname -s) != Linux ]]; then
|
|
printf 'Fuzzing is only supported on Linux\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
CC=${CC:-clang}
|
|
CXX=${CXX:-clang++}
|
|
|
|
default_fuzz_flags=-fsanitize=fuzzer,address,undefined
|
|
|
|
export CFLAGS="$default_fuzz_flags $CFLAGS"
|
|
export CXXFLAGS="$default_fuzz_flags $CXXFLAGS"
|
|
|
|
make CC="$CC" CXX="$CXX" libtree-sitter.a
|
|
|
|
if [[ -z $* ]]; then
|
|
mapfile -t languages < <(ls test/fixtures/grammars)
|
|
else
|
|
languages=("$@")
|
|
fi
|
|
|
|
mkdir -p test/fuzz/out
|
|
|
|
for lang in "${languages[@]}"; do
|
|
# skip typescript & php
|
|
if [[ $lang == typescript || $lang == php ]]; then
|
|
continue
|
|
fi
|
|
printf 'Building %s fuzzer...\n' "$lang"
|
|
lang_dir="test/fixtures/grammars/$lang"
|
|
lang_grammar="${lang_dir}/src/grammar.json"
|
|
|
|
# The following assumes each language is implemented as src/parser.c plus an
|
|
# optional scanner in src/scanner.c
|
|
objects=()
|
|
|
|
lang_scanner="${lang_dir}/src/scanner"
|
|
if [[ -f "${lang_scanner}.c" ]]; then
|
|
$CC $CFLAGS -std=c11 -g -O1 -I "${lang_dir}/src" -c "${lang_scanner}.c" -o "${lang_scanner}.o"
|
|
objects+=("${lang_scanner}.o")
|
|
fi
|
|
|
|
# Compiling with -O0 speeds up the build dramatically
|
|
$CC $CFLAGS -g -O0 -I "${lang_dir}/src" "${lang_dir}/src/parser.c" -c -o "${lang_dir}/src/parser.o"
|
|
objects+=("${lang_dir}/src/parser.o")
|
|
|
|
highlights_filename="${lang_dir}/queries/highlights.scm"
|
|
if [[ -f "${highlights_filename}" ]]; then
|
|
ts_lang_query_filename="${lang}.scm"
|
|
cp "${highlights_filename}" "test/fuzz/out/${ts_lang_query_filename}"
|
|
else
|
|
ts_lang_query_filename=""
|
|
fi
|
|
|
|
ts_lang="tree_sitter_$(jq -r .name "$lang_grammar")"
|
|
$CXX $CXXFLAGS -std=c++11 -Ilib/include \
|
|
-D TS_LANG="$ts_lang" \
|
|
-D TS_LANG_QUERY_FILENAME="\"${ts_lang_query_filename}\"" \
|
|
test/fuzz/fuzzer.cc \
|
|
"${objects[@]}" \
|
|
libtree-sitter.a \
|
|
-o "test/fuzz/out/${lang}_fuzzer"
|
|
|
|
jq '
|
|
[ ..
|
|
| if .type? == "STRING" or (.type? == "ALIAS" and .named? == false) then .value else empty end
|
|
| select(test("\\S") and length == utf8bytelength)
|
|
] | unique | .[]
|
|
' "$lang_grammar" | sort > "test/fuzz/out/${lang}.dict"
|
|
done
|