From 076c771fd4da9461f478cb2f4edcf7147e7bb5c0 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 7 Dec 2023 23:17:17 -0600 Subject: [PATCH 1/5] fix: use cargo-metadata to support init command in workspace --- Cargo.lock | 120 +++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 1 + src/project.rs | 32 ++++++------- 3 files changed, 126 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80fae15..e1733ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,12 +55,22 @@ dependencies = [ "serde", ] +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + [[package]] name = "cargo-fuzz" version = "0.11.2" dependencies = [ "anyhow", "assert_cmd", + "cargo_metadata", "clap", "current_platform", "predicates", @@ -69,6 +79,29 @@ dependencies = [ "toml", ] +[[package]] +name = "cargo-platform" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.0.77" @@ -106,7 +139,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -236,6 +269,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + [[package]] name = "libc" version = "0.2.138" @@ -320,7 +359,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.105", "version_check", ] @@ -337,18 +376,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -417,17 +456,51 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + [[package]] name = "semver" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +dependencies = [ + "serde", +] [[package]] name = "serde" -version = "1.0.149" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] [[package]] name = "strsim" @@ -446,6 +519,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -475,6 +559,26 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "toml" version = "0.5.9" diff --git a/Cargo.toml b/Cargo.toml index ae30e61..606f101 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ clap = { version = "4.0.29", features = ["derive", "deprecated"] } tempfile = "3.3.0" toml = "0.5.9" rustc_version = "0.4.0" +cargo_metadata = "0.18.1" [dev-dependencies] assert_cmd = "2.0.7" diff --git a/src/project.rs b/src/project.rs index b4da718..e376d65 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,6 +1,7 @@ use crate::options::{self, BuildMode, BuildOptions, Sanitizer}; use crate::utils::default_target; use anyhow::{anyhow, bail, Context, Result}; +use cargo_metadata::MetadataCommand; use std::collections::HashSet; use std::io::Read; use std::io::Write; @@ -931,25 +932,18 @@ pub struct Manifest { impl Manifest { pub fn parse(path: &Path) -> Result { - let contents = fs::read(path)?; - let value: toml::Value = toml::from_slice(&contents)?; - let package = value - .as_table() - .and_then(|v| v.get("package")) - .and_then(toml::Value::as_table); - let crate_name = package - .and_then(|v| v.get("name")) - .and_then(toml::Value::as_str) - .with_context(|| anyhow!("{} (package.name) is malformed", path.display()))? - .to_owned(); - let edition = package - .expect("can't be None at this point") - .get("edition") - .map(|v| match v.as_str() { - Some(s) => Ok(s.to_owned()), - None => bail!("{} (package.edition) is malformed", path.display()), - }) - .transpose()?; + let metatdata = MetadataCommand::new().exec()?; + let package = metatdata + .packages + .iter() + .find(|p| p.manifest_path == path) + .expect({ + let path = path.display(); + &format!("could not find package for {}", path) + }); + let crate_name = package.name.clone(); + let edition = Some(String::from(package.edition.as_str())); + Ok(Manifest { crate_name, edition, From 51f781ee50db11e218e63c81be27c05e87ee6cc8 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 8 Dec 2023 00:20:25 -0600 Subject: [PATCH 2/5] add workspace entry to tests to not pick up cargo-fuzz's toml --- tests/tests/project.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests/project.rs b/tests/tests/project.rs index 8826dd4..5652df6 100644 --- a/tests/tests/project.rs +++ b/tests/tests/project.rs @@ -140,6 +140,7 @@ impl ProjectBuilder { "Cargo.toml", &format!( r#" + [workspace] [package] name = "{name}" version = "1.0.0" From a4a946e8fd4f945f042691b23f5a04d7f34c98bd Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 8 Dec 2023 00:21:02 -0600 Subject: [PATCH 3/5] remove unnecessary path --- src/options/add.rs | 3 +-- src/project.rs | 14 +++----------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/options/add.rs b/src/options/add.rs index fa8adf6..0cc13b8 100644 --- a/src/options/add.rs +++ b/src/options/add.rs @@ -15,8 +15,7 @@ pub struct Add { impl RunCommand for Add { fn run_command(&mut self) -> Result<()> { let project = FuzzProject::new(self.fuzz_dir_wrapper.fuzz_dir.to_owned())?; - let fuzz_manifest_path = project.fuzz_dir().join("Cargo.toml"); - let manifest = Manifest::parse(&fuzz_manifest_path)?; + let manifest = Manifest::parse()?; project.add_target(self, &manifest) } } diff --git a/src/project.rs b/src/project.rs index e376d65..dc9e2c9 100644 --- a/src/project.rs +++ b/src/project.rs @@ -53,8 +53,7 @@ impl FuzzProject { pub fn init(init: &options::Init, fuzz_dir_opt: Option) -> Result { let project = Self::manage_initial_instance(fuzz_dir_opt)?; let fuzz_project = project.fuzz_dir(); - let root_project_manifest_path = project.project_dir.join("Cargo.toml"); - let manifest = Manifest::parse(&root_project_manifest_path)?; + let manifest = Manifest::parse()?; // TODO: check if the project is already initialized fs::create_dir(fuzz_project) @@ -931,16 +930,9 @@ pub struct Manifest { } impl Manifest { - pub fn parse(path: &Path) -> Result { + pub fn parse() -> Result { let metatdata = MetadataCommand::new().exec()?; - let package = metatdata - .packages - .iter() - .find(|p| p.manifest_path == path) - .expect({ - let path = path.display(); - &format!("could not find package for {}", path) - }); + let package = metatdata.packages.first().expect("at least one package"); let crate_name = package.name.clone(); let edition = Some(String::from(package.edition.as_str())); From 3a91261ea379943c256ea022f83e418a614a634f Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 11 Dec 2023 15:23:40 -0600 Subject: [PATCH 4/5] return error as suggested by reviewer --- src/project.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/project.rs b/src/project.rs index dc9e2c9..61a9649 100644 --- a/src/project.rs +++ b/src/project.rs @@ -932,7 +932,12 @@ pub struct Manifest { impl Manifest { pub fn parse() -> Result { let metatdata = MetadataCommand::new().exec()?; - let package = metatdata.packages.first().expect("at least one package"); + let package = metatdata.packages.first().with_context(|| { + anyhow!( + "Expected to find at least one package in {}", + metatdata.target_directory + ) + })?; let crate_name = package.name.clone(); let edition = Some(String::from(package.edition.as_str())); From f3865de0d65a8a00c8ebb110df818b181de442ba Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 11 Dec 2023 21:29:15 -0600 Subject: [PATCH 5/5] do not rely on pre rustc-0.1.73 panic msg --- tests/tests/main.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/tests/main.rs b/tests/tests/main.rs index b62f340..c3f2c7f 100644 --- a/tests/tests/main.rs +++ b/tests/tests/main.rs @@ -224,7 +224,8 @@ fn run_with_crash() { .env("RUST_BACKTRACE", "1") .assert() .stderr( - predicate::str::contains("panicked at 'I'm afraid of number 7'") + predicate::str::contains("thread '' panicked at") + .and(predicate::str::contains("I'm afraid of number 7")) .and(predicate::str::contains("ERROR: libFuzzer: deadly signal")) .and(predicate::str::contains("run_with_crash::fail_fuzzing")) .and(predicate::str::contains( @@ -317,7 +318,8 @@ fn run_without_sanitizer_with_crash() { .env("RUST_BACKTRACE", "1") .assert() .stderr( - predicate::str::contains("panicked at 'I'm afraid of number 7'") + predicate::str::contains("thread '' panicked at") + .and(predicate::str::contains("I'm afraid of number 7")) .and(predicate::str::contains("ERROR: libFuzzer: deadly signal")) .and(predicate::str::contains("run_without_sanitizer_with_crash::fail_fuzzing")) .and(predicate::str::contains(