chore(es/minifier): Configure fuzzer (#6246)

This commit is contained in:
Donny/강동윤 2022-10-25 13:36:03 +09:00 committed by GitHub
parent 3d9c1a55bb
commit d4544884ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 2034 additions and 4 deletions

View File

@ -0,0 +1,3 @@
target
corpus
artifacts

1887
crates/swc_ecma_minifier/fuzz/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
[package]
authors = ["Automatically generated"]
edition = "2018"
name = "swc_ecma_minifier-fuzz"
publish = false
version = "0.0.0"
[package.metadata]
cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4"
swc_common = { path = "../../swc_common", features = ["arbitrary"] }
swc_ecma_ast = { path = "../../swc_ecma_ast", features = ["arbitrary"] }
swc_ecma_codegen = { path = "../../swc_ecma_codegen" }
swc_ecma_minifier = { path = ".." }
swc_ecma_parser = { path = "../../swc_ecma_parser" }
swc_ecma_testing = { path = "../../swc_ecma_testing" }
swc_ecma_transforms_base = { path = "../../swc_ecma_transforms_base" }
swc_ecma_visit = { path = "../../swc_ecma_visit" }
testing = { path = "../../testing" }
# Prevent this from interfering with workspaces
[workspace]
members = ["."]
[[bin]]
doc = false
name = "bug"
path = "fuzz_targets/bug.rs"
test = false

View File

@ -0,0 +1,113 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
use swc_common::{sync::Lrc, FileName, Mark, SourceMap};
use swc_ecma_ast::{Module, Program};
use swc_ecma_codegen::text_writer::{omit_trailing_semi, JsWriter};
use swc_ecma_minifier::{
optimize,
option::{ExtraOptions, MangleOptions, MinifyOptions},
};
use swc_ecma_parser::parse_file_as_module;
use swc_ecma_testing::{exec_node_js, JsExecOptions};
use swc_ecma_transforms_base::{fixer::fixer, resolver};
use swc_ecma_visit::FoldWith;
fuzz_target!(|module: Module| {
testing::run_test(false, |cm, handler| {
// fuzzed code goes here
let code = print(cm.clone(), &[&module], true);
{
// Fuzzing produced a syntax error
if exec_node_js(
&code,
JsExecOptions {
cache: false,
..Default::default()
},
)
.is_err()
{
return Ok(());
}
}
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
let fm = cm.new_source_file(FileName::Anon, code);
let mut program = parse_file_as_module(
&fm,
Default::default(),
Default::default(),
None,
&mut vec![],
)
.map_err(|err| {
err.into_diagnostic(handler).emit();
})
.map(Program::Module)
.unwrap();
program = program.fold_with(&mut resolver(unresolved_mark, top_level_mark, false));
let output = optimize(
program,
cm.clone(),
None,
None,
&MinifyOptions {
compress: Some(Default::default()),
mangle: Some(MangleOptions {
top_level: true,
..Default::default()
}),
..Default::default()
},
&ExtraOptions {
unresolved_mark,
top_level_mark,
},
)
.expect_module();
let output = output.fold_with(&mut fixer(None));
let code = print(cm, &[output], true);
exec_node_js(
&code,
JsExecOptions {
cache: false,
..Default::default()
},
)
.unwrap();
Ok(())
})
.unwrap();
});
fn print<N: swc_ecma_codegen::Node>(cm: Lrc<SourceMap>, nodes: &[N], minify: bool) -> String {
let mut buf = vec![];
{
let mut emitter = swc_ecma_codegen::Emitter {
cfg: swc_ecma_codegen::Config {
minify,
..Default::default()
},
cm: cm.clone(),
comments: None,
wr: omit_trailing_semi(JsWriter::new(cm, "\n", &mut buf, None)),
};
for n in nodes {
n.emit_with(&mut emitter).unwrap();
}
}
String::from_utf8(buf).unwrap()
}

View File

@ -1,7 +1,5 @@
use std::{iter::once, mem::take};
#[allow(unused_imports)]
use retain_mut::RetainMut;
use rustc_hash::{FxHashMap, FxHashSet};
use swc_atoms::{js_word, JsWord};
use swc_common::{

View File

@ -1,7 +1,5 @@
use std::mem::take;
#[allow(unused_imports)]
use retain_mut::RetainMut;
use swc_atoms::js_word;
use swc_common::{util::take::Take, Spanned, DUMMY_SP};
use swc_ecma_ast::*;