diff --git a/Cargo.lock b/Cargo.lock index 9cbf5399..3093ea84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3814,6 +3814,7 @@ dependencies = [ "serde_json", "serde_json_path", "serde_yaml", + "shlex", "subfeature", "tar", "terminal-link", diff --git a/Cargo.toml b/Cargo.toml index 66680020..85b4a986 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,7 @@ serde-sarif = "0.8.0" serde_json = "1.0.145" serde_json_path = "0.7.2" serde_yaml = "0.9.34" +shlex = "1.3.0" subfeature = { path = "crates/subfeature", version = "0.0.3" } tar = "0.4.44" terminal-link = "0.1.0" diff --git a/crates/zizmor/Cargo.toml b/crates/zizmor/Cargo.toml index 85125ce6..71c4973b 100644 --- a/crates/zizmor/Cargo.toml +++ b/crates/zizmor/Cargo.toml @@ -56,6 +56,7 @@ serde = { workspace = true, features = ["derive"] } serde-sarif.workspace = true serde_json.workspace = true serde_yaml.workspace = true +shlex.workspace = true subfeature.workspace = true tar.workspace = true terminal-link.workspace = true diff --git a/crates/zizmor/src/audit/use_trusted_publishing.rs b/crates/zizmor/src/audit/use_trusted_publishing.rs index cc7e7619..e9bb3487 100644 --- a/crates/zizmor/src/audit/use_trusted_publishing.rs +++ b/crates/zizmor/src/audit/use_trusted_publishing.rs @@ -149,40 +149,46 @@ static KNOWN_TRUSTED_PUBLISHING_ACTIONS: LazyLock = - LazyLock::new(|| RegexSet::new(NON_TP_COMMAND_PATTERNS).unwrap()); + LazyLock::new(|| RegexSet::new(NON_TP_COMMAND_PATTERNS.iter().map(|p| p.0)).unwrap()); static NON_TP_COMMAND_PATTERN_REGEXES: LazyLock> = LazyLock::new(|| { NON_TP_COMMAND_PATTERNS .iter() - .map(|p| regex::Regex::new(p).unwrap()) + .map(|p| regex::Regex::new(p.0).unwrap()) .collect() }); @@ -255,8 +261,21 @@ impl UseTrustedPublishing { let cap_cmd = cap_node.utf8_text(run.as_bytes()).unwrap(); NON_TP_COMMAND_PATTERN_SET - .is_match(cap_cmd) - .then(|| Subfeature::new(cap_node.start_byte(), cap_cmd)) + .matches(cap_cmd) + .iter() + .next() + .and_then(|idx| { + let ignore_flags = NON_TP_COMMAND_PATTERNS.get(idx).unwrap().1; + // Unwrap assumption: we can't match anything above + // that isn't shlex-able. + let mut args = shlex::Shlex::new(cap_cmd); + + if args.any(|arg| ignore_flags.iter().any(|ign| arg == *ign)) { + None + } else { + Some(Subfeature::new(cap_node.start_byte(), cap_cmd)) + } + }) }) .cloned() .collect()) diff --git a/crates/zizmor/tests/integration/snapshot.rs b/crates/zizmor/tests/integration/snapshot.rs index eaa70644..6cda2a71 100644 --- a/crates/zizmor/tests/integration/snapshot.rs +++ b/crates/zizmor/tests/integration/snapshot.rs @@ -307,12 +307,25 @@ fn use_trusted_publishing() -> Result<()> { ); // No use-trusted-publishing findings expected here. + // See: https://github.com/zizmorcore/zizmor/issues/1191 insta::assert_snapshot!( zizmor() .input(input_under_test( "use-trusted-publishing/issue-1191-repro.yml" )) - .run()? + .run()?, + @"No findings to report. Good job! (2 suppressed)" + ); + + // No use-trusted-publishing findings expected here. + // See: https://github.com/zizmorcore/zizmor/issues/1251 + insta::assert_snapshot!( + zizmor() + .input(input_under_test( + "use-trusted-publishing/issue-1251-repro.yml" + )) + .run()?, + @"No findings to report. Good job! (1 suppressed)" ); Ok(()) diff --git a/crates/zizmor/tests/integration/snapshots/integration__snapshot__use_trusted_publishing-5.snap b/crates/zizmor/tests/integration/snapshots/integration__snapshot__use_trusted_publishing-5.snap deleted file mode 100644 index 2b1572b1..00000000 --- a/crates/zizmor/tests/integration/snapshots/integration__snapshot__use_trusted_publishing-5.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: crates/zizmor/tests/integration/snapshot.rs -expression: "zizmor().input(input_under_test(\"use-trusted-publishing/issue-1191-repro.yml\")).run()?" ---- -No findings to report. Good job! (2 suppressed) diff --git a/crates/zizmor/tests/integration/test-data/use-trusted-publishing/issue-1251-repro.yml b/crates/zizmor/tests/integration/test-data/use-trusted-publishing/issue-1251-repro.yml new file mode 100644 index 00000000..69fb1d23 --- /dev/null +++ b/crates/zizmor/tests/integration/test-data/use-trusted-publishing/issue-1251-repro.yml @@ -0,0 +1,15 @@ +# repro for https://github.com/zizmorcore/zizmor/issues/1251 +name: issue 1251 repro + +on: + workflow_call: + +jobs: + issue-1251-repro: + name: issue-1251-repro + runs-on: ubuntu-latest + permissions: {} + steps: + - name: not-vulnerable + run: | + cargo publish --dry-run --locked --no-default-features --features "${CRATE_FEATURES}"