diff --git a/crates/nu-parser/Cargo.toml b/crates/nu-parser/Cargo.toml index f4224f3bd..4df0286a6 100644 --- a/crates/nu-parser/Cargo.toml +++ b/crates/nu-parser/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" license = "MIT" name = "nu-parser" version = "0.84.1" +exclude = ["/fuzz"] [lib] bench = false diff --git a/crates/nu-parser/fuzz/.gitignore b/crates/nu-parser/fuzz/.gitignore new file mode 100644 index 000000000..b641f8c56 --- /dev/null +++ b/crates/nu-parser/fuzz/.gitignore @@ -0,0 +1,8 @@ +target +corpus +artifacts +coverage +Cargo.lock +out +seeds + diff --git a/crates/nu-parser/fuzz/Cargo.toml b/crates/nu-parser/fuzz/Cargo.toml new file mode 100644 index 000000000..db97e0f65 --- /dev/null +++ b/crates/nu-parser/fuzz/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "nu-parser-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" +nu-protocol = { path = "../../nu-protocol" } + + +[dependencies.nu-parser] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[profile.release] +debug = 1 + +[[bin]] +name = "parse" +path = "fuzz_targets/parse.rs" +test = false +doc = false diff --git a/crates/nu-parser/fuzz/README.md b/crates/nu-parser/fuzz/README.md new file mode 100644 index 000000000..131fb5023 --- /dev/null +++ b/crates/nu-parser/fuzz/README.md @@ -0,0 +1,9 @@ +# Fuzzer for `nu-parser` + +- For detailed info, please look at [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) + +# Quick start guide +- Install cargo-fuzz by `cargo install cargo-fuzz` +- Run `gather_seeds.nu` for preparing the initial seeds corpus +- Make output directory `mkdir out` +- Run the fuzzer with `cargo fuzz run parse out seeds` diff --git a/crates/nu-parser/fuzz/fuzz_targets/parse.rs b/crates/nu-parser/fuzz/fuzz_targets/parse.rs new file mode 100644 index 000000000..e62de43b1 --- /dev/null +++ b/crates/nu-parser/fuzz/fuzz_targets/parse.rs @@ -0,0 +1,13 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; + +use nu_parser::*; +use nu_protocol::engine::{EngineState, StateWorkingSet}; + +fuzz_target!(|data: &[u8]| { + let engine_state = EngineState::new(); + let mut working_set = StateWorkingSet::new(&engine_state); + + let _block = parse(&mut working_set, None, &data, true); +}); diff --git a/crates/nu-parser/fuzz/gather_seeds.nu b/crates/nu-parser/fuzz/gather_seeds.nu new file mode 100755 index 000000000..1315ce033 --- /dev/null +++ b/crates/nu-parser/fuzz/gather_seeds.nu @@ -0,0 +1,6 @@ +# Check if 'seeds' directory exists. If not, create one. +let seeds_exists = "./seeds" | path exists +if $seeds_exists == false { mkdir seeds } + +# Gather all "*.nu" files from '../..' and copy them into 'seeds' +ls ../../**/*.nu | get name | each {|f| cp $f ./seeds/} diff --git a/crates/nu-parser/fuzz/rust-toolchain.toml b/crates/nu-parser/fuzz/rust-toolchain.toml new file mode 100644 index 000000000..5d56faf9a --- /dev/null +++ b/crates/nu-parser/fuzz/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/crates/nu-path/Cargo.toml b/crates/nu-path/Cargo.toml index b1fba8231..de44e3db1 100644 --- a/crates/nu-path/Cargo.toml +++ b/crates/nu-path/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" license = "MIT" name = "nu-path" version = "0.84.1" +exclude = ["/fuzz"] [lib] bench = false diff --git a/crates/nu-path/fuzz/.gitignore b/crates/nu-path/fuzz/.gitignore new file mode 100644 index 000000000..7d4eb0344 --- /dev/null +++ b/crates/nu-path/fuzz/.gitignore @@ -0,0 +1,7 @@ +target +corpus +artifacts +coverage +Cargo.lock +out + diff --git a/crates/nu-path/fuzz/Cargo.toml b/crates/nu-path/fuzz/Cargo.toml new file mode 100644 index 000000000..08121602d --- /dev/null +++ b/crates/nu-path/fuzz/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "nu-path-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.nu-path] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[profile.release] +debug = 1 + +[[bin]] +name = "path" +path = "fuzz_targets/path_fuzzer.rs" +test = false +doc = false diff --git a/crates/nu-path/fuzz/README.md b/crates/nu-path/fuzz/README.md new file mode 100644 index 000000000..ab16045b3 --- /dev/null +++ b/crates/nu-path/fuzz/README.md @@ -0,0 +1,8 @@ +# Fuzzer for `nu-path` + +- For detailed info, please look at [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) + +# Quick start guide +- Install cargo-fuzz by `cargo install cargo-fuzz` +- Make output directory `mkdir out` +- Run the fuzzer with `cargo fuzz run parse out` diff --git a/crates/nu-path/fuzz/fuzz_targets/path_fuzzer.rs b/crates/nu-path/fuzz/fuzz_targets/path_fuzzer.rs new file mode 100644 index 000000000..d3ccb7cdc --- /dev/null +++ b/crates/nu-path/fuzz/fuzz_targets/path_fuzzer.rs @@ -0,0 +1,25 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use nu_path::{expand_path_with, expand_tilde, expand_to_real_path, trim_trailing_slash}; + +fuzz_target!(|data: &[u8]| { + if let Ok(s) = std::str::from_utf8(data) { + let path = std::path::Path::new(s); + + // Fuzzing expand_to_real_path function + let _ = expand_to_real_path(path); + + // Fuzzing trim_trailing_slash function + let _ = trim_trailing_slash(s); + + // Fuzzing expand_tilde function + let _ = expand_tilde(path); + + // Fuzzing expand_path_with function + // Here, we're assuming a second path for the "relative to" aspect. + // For simplicity, we're just using the current directory. + let current_dir = std::path::Path::new("."); + let _ = expand_path_with(path, ¤t_dir); + } +}); diff --git a/crates/nu-path/fuzz/rust-toolchain.toml b/crates/nu-path/fuzz/rust-toolchain.toml new file mode 100644 index 000000000..5d56faf9a --- /dev/null +++ b/crates/nu-path/fuzz/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly"