diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-03 22:47:33 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-03 22:47:33 +0900 |
| commit | 2b48ae7bcf857bc35de95968513750c2d6e6de7b (patch) | |
| tree | 3b76b3e3b673c5f4e8fbd20775e35d062e73b1f7 /crates/mozart/src/commands | |
| parent | cccdce42f6eb5c21179bf7b2fbd482a7d29c3b9d (diff) | |
| download | php-mozart-2b48ae7bcf857bc35de95968513750c2d6e6de7b.tar.gz php-mozart-2b48ae7bcf857bc35de95968513750c2d6e6de7b.tar.zst php-mozart-2b48ae7bcf857bc35de95968513750c2d6e6de7b.zip | |
fix(resolver): honor config.audit.block-insecure security-advisory filter
Mozart silently ignored the `security-advisories` block on inline
`type: package` repositories and the `config.audit.block-insecure`
audit flag, so a `composer update` succeeded with packages a Composer
run would have refused to load. Mirror Composer's
`SecurityAdvisoryPoolFilter` for the slice that feeds the pool:
- Plumb a `security-advisories` field through `RawRepository` and a
`block_insecure` flag through `ResolveRequest`, lifted off
`composer.json`'s `config.audit.block-insecure`.
- Collect every advisory's `affectedVersions` constraint at resolve
time. When `block_insecure` is set and an inline package's
normalized version satisfies the constraint, drop it from the pool
before solving — root requires with no unaffected candidate then
fail with the standard "could not be resolved" error.
Diffstat (limited to 'crates/mozart/src/commands')
| -rw-r--r-- | crates/mozart/src/commands/create_project.rs | 1 | ||||
| -rw-r--r-- | crates/mozart/src/commands/init.rs | 2 | ||||
| -rw-r--r-- | crates/mozart/src/commands/remove.rs | 4 | ||||
| -rw-r--r-- | crates/mozart/src/commands/require.rs | 3 | ||||
| -rw-r--r-- | crates/mozart/src/commands/update.rs | 20 |
5 files changed, 26 insertions, 4 deletions
diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs index a7964ae..61cb886 100644 --- a/crates/mozart/src/commands/create_project.rs +++ b/crates/mozart/src/commands/create_project.rs @@ -445,6 +445,7 @@ pub async fn execute( block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; console.info("Resolving dependencies..."); diff --git a/crates/mozart/src/commands/init.rs b/crates/mozart/src/commands/init.rs index 1a6df37..209be4b 100644 --- a/crates/mozart/src/commands/init.rs +++ b/crates/mozart/src/commands/init.rs @@ -707,6 +707,7 @@ fn parse_repositories(repos: &[String]) -> anyhow::Result<Vec<RawRepository>> { only: None, exclude: None, canonical: None, + security_advisories: None, }); } else { // Plain URL @@ -717,6 +718,7 @@ fn parse_repositories(repos: &[String]) -> anyhow::Result<Vec<RawRepository>> { only: None, exclude: None, canonical: None, + security_advisories: None, }); } } diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs index c52d410..d4b3aef 100644 --- a/crates/mozart/src/commands/remove.rs +++ b/crates/mozart/src/commands/remove.rs @@ -279,6 +279,7 @@ pub async fn execute( block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; // Print header messages @@ -567,6 +568,7 @@ async fn remove_unused( block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; console.info("Resolving dependencies to detect unused packages..."); @@ -925,6 +927,7 @@ mod tests { block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; let resolved = resolve(&request) .await @@ -986,6 +989,7 @@ mod tests { block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; let resolved2 = resolve(&request2) .await diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs index 3ff5ced..b302ed9 100644 --- a/crates/mozart/src/commands/require.rs +++ b/crates/mozart/src/commands/require.rs @@ -667,6 +667,7 @@ pub async fn execute( block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; // Print header messages @@ -1079,6 +1080,7 @@ mod tests { block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; let resolved = resolver::resolve(&request) @@ -1158,6 +1160,7 @@ mod tests { block_abandoned: false, root_branch_alias: None, preferred_versions: indexmap::IndexMap::new(), + block_insecure: false, }; let resolved = resolver::resolve(&request) diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs index 3736266..0439cfa 100644 --- a/crates/mozart/src/commands/update.rs +++ b/crates/mozart/src/commands/update.rs @@ -1249,6 +1249,17 @@ pub async fn run( .and_then(|a| a.get("block-abandoned")) .and_then(|v| v.as_bool()) .unwrap_or(false); + // Mirrors `Composer\Advisory\AuditConfig::fromConfig`: `block-insecure` + // turns the security-advisory data into a hard filter — affected + // versions are dropped from the pool, so a root require with no + // unaffected candidates fails resolution before any side effects. + let block_insecure = composer_json + .extra_fields + .get("config") + .and_then(|c| c.get("audit")) + .and_then(|a| a.get("block-insecure")) + .and_then(|v| v.as_bool()) + .unwrap_or(false); // For `--minimal-changes`, feed the lock's pinned versions into the // resolver as preferred-version overrides. The packages the user @@ -1327,6 +1338,7 @@ pub async fn run( block_abandoned, root_branch_alias: extract_root_branch_alias(&composer_json), preferred_versions, + block_insecure, }; // Step 6: Print header and run resolver @@ -1496,10 +1508,9 @@ pub async fn run( // doesn't masquerade as a content update. When the source or dist type // changed (`hg` → `git`, etc.), the new entry is left as-is so the // change still emits the install-step Update operation. - if update_mirrors - && let Some(old) = &old_lock { - apply_mirror_ref_overrides(&mut new_lock, old); - } + if update_mirrors && let Some(old) = &old_lock { + apply_mirror_ref_overrides(&mut new_lock, old); + } // Step 10: Compute and print change report let changes = compute_update_changes(old_lock.as_ref(), &new_lock, dev_mode); @@ -2476,6 +2487,7 @@ mod tests { block_abandoned: false, root_branch_alias: None, preferred_versions: IndexMap::new(), + block_insecure: false, }; let resolved = resolve(&request).await.expect("Resolution should succeed"); |
