This adds support for fuzzing tree-sitter grammars with libFuzzer. This currently only works on Linux because of linking issues on macOS. Breifly, the AddressSanitizer library is dynamically linked into the fuzzer binary and cannot be found at runtime if built with a compiler that wasn't provided by Xcode(?). The runtime library is statically linked on Linux so this isn't a problem.
31 lines
795 B
Python
31 lines
795 B
Python
import json
|
|
import sys
|
|
|
|
def find_literals(literals, node):
|
|
'''Recursively find STRING literals in the grammar definition'''
|
|
|
|
if type(node) is dict:
|
|
if 'type' in node and node['type'] == 'STRING' and 'value' in node:
|
|
literals.add(node['value'])
|
|
|
|
for key, value in node.iteritems():
|
|
find_literals(literals, value)
|
|
|
|
elif type(node) is list:
|
|
for item in node:
|
|
find_literals(literals, item)
|
|
|
|
def main():
|
|
'''Generate a libFuzzer / AFL dictionary from a tree-sitter grammar.json'''
|
|
with open(sys.argv[1]) as f:
|
|
grammar = json.load(f)
|
|
|
|
literals = set()
|
|
find_literals(literals, grammar)
|
|
|
|
for lit in sorted(literals):
|
|
if lit:
|
|
print '"%s"' % ''.join([(c if c.isalnum() else '\\x%02x' % ord(c)) for c in lit])
|
|
|
|
if __name__ == '__main__':
|
|
main()
|