Skip to content

Commit d8b1672

Browse files
committed
fuzz: initial integration
- Adds initial fuzz_target for Handlebars.compile() - Adds Jazzer.js as dev-dependency - Adds fuzzing on Github CI
1 parent 1fc4ef0 commit d8b1672

File tree

62 files changed

+2878
-414
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2878
-414
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ jobs:
5858
cd ./tests/integration/webpack-babel-test && ./test.sh && cd -
5959
cd ./tests/integration/webpack-test && ./test.sh && cd -
6060
61+
- name: Fuzz Test
62+
# Runs for 3 minutes
63+
run: cd ./fuzz && ./test.sh 180 && cd -
64+
6165
browser:
6266
name: Test (Browser)
6367
runs-on: 'ubuntu-22.04'

fuzz/README.md

Lines changed: 45 additions & 0 deletions

fuzz/compiler.fuzz.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const Handlebars = require('../dist/cjs/handlebars')['default'];
2+
3+
const ignored = [
4+
'Parse error',
5+
'Lexical error',
6+
`doesn't match`,
7+
'Invalid path',
8+
'Unsupported number of partial arguments',
9+
];
10+
11+
function ignoredError(error) {
12+
return !!ignored.some((message) => error.message.includes(message));
13+
}
14+
15+
/**
16+
* @param {Buffer} data
17+
*/
18+
module.exports.fuzz = function (data) {
19+
try {
20+
const ast = Handlebars.parse(data.toString());
21+
Handlebars.compile(ast, {});
22+
} catch (error) {
23+
if (error.message && !ignoredError(error)) {
24+
throw error;
25+
}
26+
}
27+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes as |value index|}}{{index}}. {{value.text}}!{{/each}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}{{name}}{{else if none}}{{none}}{{/people}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{../name}}{{../name}}{{/goodbyes}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{foo.bar (baz bat=1)}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
\n {{#if}}\n{{/def}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#helper}}{{*decorator}}{{/helper}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#foo}} {{/foo}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{foo.bar baz "foo" true false bat=1}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#foo}} {{foo}}{{/foo}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#helper}}{{*decorator foo}}{{/helper}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#none}}\n{{.}}\n{{^}}\nFail\n{{/none}}\n
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}{{name}}{{^}}{{none}}{{/people}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each data}}{{@index}}:{{a}} {{/each}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{foo}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}{{name}}{{else if none}}{{none}}{{/if}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{foo.bar baz bat=1}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{*decorator foo}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#with person}}{{first}} {{last}}{{/with}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#with person}}Person is present{{else}}Person is not present{{/with}}'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<b>#1</b>. goodbye! 2. GOODBYE! cruel world!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#goodbyes}}{{/goodbyes}}cruel {{world}}!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{foo.bar}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{*decorator "success"}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#helper}}{{*decorator}}suc{{/helper}}

fuzz/test.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
if [ $# -eq 0 ]; then
6+
echo "Usage: $0 <max_total_time>
7+
The <max_total_time> is passed to the internal fuzzing engine
8+
(libFuzzer) to stop the fuzzing run after 'N' seconds."
9+
exit 1
10+
fi
11+
12+
max_total_time=$1
13+
14+
for i in ./*.fuzz.js; do
15+
target=$(basename "$i" .js)
16+
echo "-- Running $target for $max_total_time seconds."
17+
npx jazzer $target corpus/$target --sync -- -max_total_time=$max_total_time;
18+
done

0 commit comments

Comments
 (0)