[fuzzer] Make fuzzer work with Forget
Remove v8 specific bits. It's still not very useful as we barely have any tests that can be used as input corpus.
Sathya Gunasekaran committed
Jul 6, 2023 at 11:44 UTC
853d0b1b69313177ab441e0e674c3d3776994247
5 files changed
+32
-88
compiler/forget/.prettierignore
+2
-1
@@ -8,4 +8,5 @@ test262/
8
*.md
9
*.json
10
*.css
11
-*.webmanifest
\ No newline at end of file
11
+*.webmanifest
12
+packages/js-fuzzer
\ No newline at end of file
compiler/forget/packages/js-fuzzer/.gitignore
+1
@@ -4,3 +4,4 @@
4
/output.zip
5
/output/
6
/workdir/
7
+web-tests/
\ No newline at end of file
compiler/forget/packages/js-fuzzer/run.js
+28
-81
@@ -38,22 +38,26 @@ function getRandomInputs(primaryCorpus, secondaryCorpora, count) {
38
39
let inputs = primaryCorpus.getRandomTestcases(primaryCount);
40
41
+ // TODO(gsn): Uncomment this once we have more tests to build a
42
+ // secondary corpora.
43
+ //
44
// Split remainder equally between the secondary corpora.
42
- const secondaryCount = Math.floor(count / secondaryCorpora.length);
43
-
44
- for (let i = 0; i < secondaryCorpora.length; i++) {
45
- let currentCount = secondaryCount;
46
- if (i == secondaryCorpora.length - 1) {
47
- // Last one takes the remainder.
48
- currentCount = count;
49
- }
50
-
51
- count -= currentCount;
52
- if (currentCount) {
53
- inputs = inputs.concat(
54
- secondaryCorpora[i].getRandomTestcases(currentCount));
55
- }
56
- }
45
+ // const secondaryCount = Math.floor(count / secondaryCorpora.length);
46
+
47
+ // for (let i = 0; i < secondaryCorpora.length; i++) {
48
+ // let currentCount = secondaryCount;
49
+ // if (i == secondaryCorpora.length - 1) {
50
+ // // Last one takes the remainder.
51
+ // currentCount = count;
52
+ // }
53
+
54
+ // count -= currentCount;
55
+ // if (currentCount) {
56
+ // inputs = inputs.concat(
57
+ // secondaryCorpora[i].getRandomTestcases(currentCount)
58
+ // );
59
+ // }
60
+ // }
61
62
return random.shuffle(inputs);
63
}
@@ -65,47 +69,18 @@ function collect(value, total) {
69
70
function overrideSettings(settings, settingOverrides) {
71
for (const setting of settingOverrides) {
68
- const parts = setting.split('=');
72
+ const parts = setting.split("=");
73
settings[parts[0]] = parseFloat(parts[1]);
74
}
75
}
76
73
-function* randomInputGen(engine) {
77
+function* randomInputGen() {
78
const inputDir = path.resolve(program.input_dir);
79
76
- const v8Corpus = new corpus.Corpus(inputDir, 'v8');
77
- const chakraCorpus = new corpus.Corpus(inputDir, 'chakra');
78
- const spiderMonkeyCorpus = new corpus.Corpus(inputDir, 'spidermonkey');
79
- const jscCorpus = new corpus.Corpus(inputDir, 'WebKit/JSTests');
80
- const crashTestsCorpus = new corpus.Corpus(inputDir, 'CrashTests');
80
+ const reactCorpus = new corpus.Corpus(inputDir, "react");
81
82
for (let i = 0; i < program.no_of_files; i++) {
83
- let inputs;
84
- if (engine === 'V8') {
85
- inputs = getRandomInputs(
86
- v8Corpus,
87
- random.shuffle([chakraCorpus, spiderMonkeyCorpus, jscCorpus,
88
- crashTestsCorpus, v8Corpus]),
89
- MAX_TEST_INPUTS_PER_TEST);
90
- } else if (engine == 'chakra') {
91
- inputs = getRandomInputs(
92
- chakraCorpus,
93
- random.shuffle([v8Corpus, spiderMonkeyCorpus, jscCorpus,
94
- crashTestsCorpus]),
95
- MAX_TEST_INPUTS_PER_TEST);
96
- } else if (engine == 'spidermonkey') {
97
- inputs = getRandomInputs(
98
- spiderMonkeyCorpus,
99
- random.shuffle([v8Corpus, chakraCorpus, jscCorpus,
100
- crashTestsCorpus]),
101
- MAX_TEST_INPUTS_PER_TEST);
102
- } else {
103
- inputs = getRandomInputs(
104
- jscCorpus,
105
- random.shuffle([chakraCorpus, spiderMonkeyCorpus, v8Corpus,
106
- crashTestsCorpus]),
107
- MAX_TEST_INPUTS_PER_TEST);
108
- }
83
+ let inputs = getRandomInputs(reactCorpus, [], MAX_TEST_INPUTS_PER_TEST);
84
85
if (inputs.length > 0) {
86
yield inputs;
@@ -158,31 +133,8 @@ function main() {
133
overrideSettings(settings, program.setting);
134
}
135
161
- let app_name = process.env.APP_NAME;
162
- if (app_name && app_name.endsWith('.exe')) {
163
- app_name = app_name.substr(0, app_name.length - 4);
164
- }
165
-
166
- if (app_name === 'd8' ||
167
- app_name === 'v8_simple_inspector_fuzzer' ||
168
- app_name === 'v8_foozzie.py') {
169
- // V8 supports running the raw d8 executable, the inspector fuzzer or
170
- // the differential fuzzing harness 'foozzie'.
171
- settings.engine = 'V8';
172
- } else if (app_name === 'ch') {
173
- settings.engine = 'chakra';
174
- } else if (app_name === 'js') {
175
- settings.engine = 'spidermonkey';
176
- } else if (app_name === 'jsc') {
177
- settings.engine = 'jsc';
178
- } else {
179
- console.log('ERROR: Invalid APP_NAME');
180
- process.exit(1);
181
- }
182
-
183
- const mode = process.env.FUZZ_MODE || 'default';
184
- assert(mode in SCRIPT_MUTATORS, `Unknown mode ${mode}`);
185
- const mutator = new SCRIPT_MUTATORS[mode](settings);
136
+ settings.engine = "node";
137
+ const mutator = new SCRIPT_MUTATORS["default"](settings);
138
139
if (program.mutate) {
140
const absPath = path.resolve(program.mutate);
@@ -200,23 +152,18 @@ function main() {
152
if (program.mutate_corpus) {
153
inputGen = corpusInputGen();
154
} else {
203
- inputGen = randomInputGen(settings.engine);
155
+ inputGen = randomInputGen();
156
}
157
158
for (const [i, inputs] of enumerate(inputGen)) {
207
- const outputPath = path.join(program.output_dir, 'fuzz-' + i + '.js');
159
+ const outputPath = path.join(program.output_dir, "fuzz-" + i + ".js");
160
161
const start = Date.now();
210
- const paths = inputs.map(input => input.relPath);
162
+ const paths = inputs.map((input) => input.relPath);
163
164
try {
165
const mutated = mutator.mutateMultiple(inputs);
166
fs.writeFileSync(outputPath, mutated.code);
215
-
216
- if (settings.engine === 'V8' && mutated.flags && mutated.flags.length > 0) {
217
- const flagsPath = path.join(program.output_dir, 'flags-' + i + '.js');
218
- fs.writeFileSync(flagsPath, mutated.flags.join(' '));
219
- }
167
} catch (e) {
168
if (e.message.startsWith('ENOSPC')) {
169
console.log('ERROR: No space left. Bailing out...');
compiler/forget/packages/js-fuzzer/script_mutator.js
-5
@@ -16,7 +16,6 @@ const db = require('./db.js');
16
const random = require('./random.js');
17
const sourceHelpers = require('./source_helpers.js');
18
19
-const { AddTryCatchMutator } = require('./mutators/try_catch.js');
19
const { ArrayMutator } = require('./mutators/array_mutator.js');
20
const { CrossOverMutator } = require('./mutators/crossover_mutator.js');
21
const { ExpressionMutator } = require('./mutators/expression_mutator.js');
@@ -67,7 +66,6 @@ class ScriptMutator {
66
new FunctionCallMutator(settings),
67
new VariableOrObjectMutator(settings),
68
];
70
- this.trycatch = new AddTryCatchMutator(settings);
69
this.settings = settings;
70
}
71
@@ -150,9 +148,6 @@ class ScriptMutator {
148
}
149
}
150
153
- // Try-catch wrapping should always be the last mutation.
154
- mutators.push(this.trycatch);
155
-
151
for (const mutator of mutators) {
152
mutator.mutate(source);
153
}
compiler/forget/packages/js-fuzzer/source_helpers.js
+1
-1
@@ -26,7 +26,7 @@ const V8_REPLACE_BUILTIN_REGEXP = new RegExp(
26
V8_BUILTIN_PREFIX + '(\\w+)\\(', 'g');
27
28
const BABYLON_OPTIONS = {
29
- sourceType: 'script',
29
+ sourceType: 'module',
30
allowReturnOutsideFunction: true,
31
tokens: false,
32
ranges: false,