This repository has been archived by the owner on Sep 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 40
/
fuzz-test.js
88 lines (69 loc) · 1.7 KB
/
fuzz-test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const fs = require('fs');
const generateRandomJs = require('eslump/codegen.js');
const acorn = require('acorn');
const { walk } = require('estree-walker');
const butternut = require('../dist/butternut.cjs.js');
const MAX = 1000;
let tested = 0;
while (tested < MAX) {
const input = generateRandomJs();
try {
const ast = acorn.parse(input, {
ecmaVersion: 8,
sourceType: 'module',
preserveParens: true,
allowReserved: true,
allowReturnOutsideFunction: true
});
if (!isValidInput(ast)) continue;
} catch (err) {
continue;
}
try {
butternut.squash(input, {
check: true,
allowDangerousEval: true
});
tested += 1;
} catch (err) {
if (err.check) {
fs.writeFileSync('test/fixture/input/_test.js', input);
throw err;
}
}
}
console.log( `successfully tested ${tested} inputs` );
function isValidInput(ast) {
let valid = true;
walk(ast, {
enter(node, parent) {
if (!valid) {
this.abort();
return;
}
if (node.type === 'MemberExpression') {
const object = deparenthesize(node.object);
// disregard nonsense like false.typeof
if (isBoolean(object)) valid = false;
}
if (node.type === 'UnaryExpression') {
const argument = deparenthesize(node.argument);
// `true ** x`
if (isBoolean(argument)) valid = false;
}
if (node.type === 'CallExpression' || node.type === 'NewExpression') {
const callee = deparenthesize(node.callee);
// `true()`
if (isBoolean(callee)) valid = false;
}
}
});
return valid;
}
function deparenthesize(node) {
while (node.type === 'ParenthesizedExpression')
node = node.expression;
}
function isBoolean(node) {
return node.type === 'Literal' && typeof node.value === 'boolean';
}