cargo-auditable icon indicating copy to clipboard operation
cargo-auditable copied to clipboard

Filtering against `cargo tree` under-includes dependencies, does not accurately reflect feature unification in a workspace

Open Shnatsel opened this issue 6 months ago • 5 comments

Uncommenting this line in #210 causes the test to fail:

https://github.com/rust-secure-code/cargo-auditable/blob/6c39a181300a31553bebb55b26441fe7cad0a223/cargo-auditable/tests/it.rs#L593

This is using the fixture runtime_and_dev_dep_with_different_features which tests for over-zealous feature unification. If a package is used both as a dev-dependency and as a normal dependency, the features enabled on it when it is used as a dev-dependency do not impact the features enabled on it in the runtime dependency tree.

cargo metadata performs the erroneous over-zealous feature unification, which is why we have to filter it against the output of cargo tree --edges=normal,build to get rid of the extraneous dependencies.

It seems that either the SBOM emitted by Cargo or our handling of it reintroduce the problem.

cc @tofay

Shnatsel avatar Jun 27 '25 01:06 Shnatsel

It seems to be a bug in the upstream SBOM support. The optional_transitive_dep crate should not be present in the SBOM emitted by Cargo, but it is: top_level_crate.cargo-sbom.json

Shnatsel avatar Jun 27 '25 01:06 Shnatsel

The cargo SBOM is correct for that test fixture if you build with -p top_level_crate. If you don't, then cargo passes all the workspace members over to the feature resolver, causing optional_transitive_dep to be activated. ~~But yeah, it's a cargo bug.~~

tofay avatar Jun 27 '25 07:06 tofay

Hmm... I don't think this is a cargo-auditable or cargo SBOM bug. Perhaps it's a cargo bug relating to workspace feature resolution but it's not a reporting bug.

I think the cargo tree approach is bugged as it will not report the dependencies that we don't think cargo should be compiling but that cargo is actually compiling.

Consider https://github.com/rust-secure-code/cargo-auditable/commit/036acd1f217edce94274c0c3a1aabea7d6572d07. When you run the example with cargo run -p top_level_crate and cargo run you get different results. The cargo SBOM accurately includes optional_transitive_dep in both cases.

tofay avatar Jun 27 '25 07:06 tofay

Consider https://github.com/rust-secure-code/cargo-auditable/commit/036acd1f217edce94274c0c3a1aabea7d6572d07. When you run the example with cargo run -p top_level_crate and cargo run you get different results.

Well that's interesting (and horrifying). Thanks for pointing it out.

The cargo SBOM accurately includes optional_transitive_dep in both cases.

To clarify, it doesn't include it in all cases. Rather, it includes optional_transitive_dep when executing cargo run workspace root, but excludes it when running cargo run -p top_level_crate in the workspace root or when doing cd top_level_crate && cargo run. This behavior matches the cargo run output and appears to be correct.

Shnatsel avatar Jun 27 '25 14:06 Shnatsel

I've updated the title of the issue and I'm going to take a long, hard look at my usage of cargo tree to try and accurately reflect this interesting behavior of Cargo.

Shnatsel avatar Jun 27 '25 14:06 Shnatsel