@samitouri / QOS-React-2 / commits / 853d0b1b69

[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,