From 519b686e930db5c5ba3180ff7a0760ddc0cedc86 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Mon, 14 Feb 2022 14:43:30 +0100 Subject: [PATCH] Check exceptions first (#407) * Check exceptions first * Update CHANGELOG --- CHANGELOG.md | 3 +++ src/licenses.rs | 31 ++++++++++++++++--------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c110e702..78738a7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Fixed +- [PR#407](https://github.com/EmbarkStudios/cargo-deny/pull/407) resolved [#406](https://github.com/EmbarkStudios/cargo-deny/issues/406) by always checking license exceptions first. + ## [0.11.2] - 2022-02-07 ### Changed - [PR#403](https://github.com/EmbarkStudios/cargo-deny/pull/403) added support for the [`CARGO_TERM_COLOR`](https://doc.rust-lang.org/cargo/reference/config.html#termcolor) environment variable. Thanks [@svenstaro](https://github.com/svenstaro)! diff --git a/src/licenses.rs b/src/licenses.rs index e4effd4a..b1d6159b 100644 --- a/src/licenses.rs +++ b/src/licenses.rs @@ -82,7 +82,21 @@ fn evaluate_expression( }); let eval_res = expr.evaluate_with_failures(|req| { - // 1. Licenses explicitly denied are of course hard failures, + // 1. Exceptions are additional per-crate licenses that aren't blanket + // allowed by all crates, note that we check these before denials so you + // can allow an exception + if let Some(ind) = exception_ind { + let exception = &cfg.exceptions[ind]; + for allow in &exception.allowed { + if allow.value.satisfies(req) { + // Note that hit the exception + hits.exceptions.as_mut_bitslice().set(ind, true); + allow!(ExplicitException); + } + } + } + + // 2. Licenses explicitly denied are of course hard failures, // but failing one license in an expression is not necessarily // going to actually ban the crate, for example, the canonical // "Apache-2.0 OR MIT" used in by a lot crates means that @@ -94,7 +108,7 @@ fn evaluate_expression( } } - // 2. A license that is specifically allowed will of course mean + // 3. A license that is specifically allowed will of course mean // that the requirement is met. for (i, allow) in cfg.allowed.iter().enumerate() { if allow.value.satisfies(req) { @@ -103,19 +117,6 @@ fn evaluate_expression( } } - // 3. Exceptions are additional per-crate licenses that aren't blanket - // allowed by all crates - if let Some(ind) = exception_ind { - let exception = &cfg.exceptions[ind]; - for allow in &exception.allowed { - if allow.value.satisfies(req) { - // Note that hit the exception - hits.exceptions.as_mut_bitslice().set(ind, true); - allow!(ExplicitException); - } - } - } - // 4. If the license isn't explicitly allowed, it still may // be allowed by the blanket "OSI Approved" or "FSF Free/Libre" // allowances