aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/dependency_resolver
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
-rw-r--r--crates/shirabe/src/dependency_resolver/pool.rs15
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_builder.rs20
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_optimizer.rs3
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_generator.rs8
-rw-r--r--crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs143
5 files changed, 142 insertions, 47 deletions
diff --git a/crates/shirabe/src/dependency_resolver/pool.rs b/crates/shirabe/src/dependency_resolver/pool.rs
index ddb4df5..708930c 100644
--- a/crates/shirabe/src/dependency_resolver/pool.rs
+++ b/crates/shirabe/src/dependency_resolver/pool.rs
@@ -8,7 +8,7 @@ use shirabe_semver::compiling_matcher::CompilingMatcher;
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
-use crate::advisory::PartialSecurityAdvisory;
+use crate::advisory::PartialOrFullSecurityAdvisory;
use crate::package::BasePackage;
use crate::package::BasePackageHandle;
use crate::package::version::VersionParser;
@@ -31,8 +31,8 @@ pub struct Pool {
/// @var array<string, array<string, string>> Map of package object hash => removed normalized versions => removed pretty version
pub(crate) removed_versions_by_package: IndexMap<String, IndexMap<String, String>>,
/// @var array<string, array<string, array<SecurityAdvisory|PartialSecurityAdvisory>>> Map of package name => normalized version => security advisories
- // TODO(phase-b): SecurityAdvisory|PartialSecurityAdvisory union — stored as PartialSecurityAdvisory base
- security_removed_versions: IndexMap<String, IndexMap<String, Vec<PartialSecurityAdvisory>>>,
+ security_removed_versions:
+ IndexMap<String, IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>>,
/// @var array<string, array<string, string>> Map of package name => normalized version => pretty version
abandoned_removed_versions: IndexMap<String, IndexMap<String, String>>,
}
@@ -49,7 +49,10 @@ impl Pool {
unacceptable_fixed_or_locked_packages: Vec<BasePackageHandle>,
removed_versions: IndexMap<String, IndexMap<String, String>>,
removed_versions_by_package: IndexMap<String, IndexMap<String, String>>,
- security_removed_versions: IndexMap<String, IndexMap<String, Vec<PartialSecurityAdvisory>>>,
+ security_removed_versions: IndexMap<
+ String,
+ IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>,
+ >,
abandoned_removed_versions: IndexMap<String, IndexMap<String, String>>,
) -> Self {
let mut this = Self {
@@ -151,7 +154,7 @@ impl Pool {
) {
return package_with_security_advisories
.iter()
- .map(|advisory| advisory.advisory_id.clone())
+ .map(|advisory| advisory.advisory_id().to_string())
.collect();
}
}
@@ -186,7 +189,7 @@ impl Pool {
/// @return array<string, array<string, array<SecurityAdvisory|PartialSecurityAdvisory>>>
pub fn get_all_security_removed_package_versions(
&self,
- ) -> &IndexMap<String, IndexMap<String, Vec<PartialSecurityAdvisory>>> {
+ ) -> &IndexMap<String, IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>> {
&self.security_removed_versions
}
diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs
index 18d2db4..1bbd51e 100644
--- a/crates/shirabe/src/dependency_resolver/pool_builder.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs
@@ -352,7 +352,7 @@ impl PoolBuilder {
// filter vulnerable packages before optimizing the pool otherwise we may end up with inconsistent state where the optimizer took away versions
// that were not vulnerable and now suddenly the vulnerable ones are removed and we are missing some versions to make it solvable
- pool = self.run_security_advisory_filter(pool, &repositories, request);
+ pool = self.run_security_advisory_filter(pool, &repositories, request)?;
pool = self.run_optimizer(request, pool);
Intervals::clear();
@@ -1110,9 +1110,9 @@ impl PoolBuilder {
pool: Pool,
repositories: &Vec<RepositoryInterfaceHandle>,
request: &Request,
- ) -> Pool {
+ ) -> anyhow::Result<Pool> {
if self.security_advisory_pool_filter.is_none() {
- return pool;
+ return Ok(pool);
}
self.io.debug("Running security advisory pool filter.", &[]);
@@ -1121,16 +1121,16 @@ impl PoolBuilder {
let total = pool.get_packages().len() as f64;
let repos_owned: Vec<RepositoryInterfaceHandle> = repositories.iter().cloned().collect();
- let pool =
- self.security_advisory_pool_filter
- .as_mut()
- .unwrap()
- .filter(pool, repos_owned, request);
+ let pool = self
+ .security_advisory_pool_filter
+ .as_mut()
+ .unwrap()
+ .filter(pool, repos_owned, request)?;
let filtered = total - (pool.get_packages().len() as f64);
if 0.0 == filtered {
- return pool;
+ return Ok(pool);
}
self.io.write3(
@@ -1154,6 +1154,6 @@ impl PoolBuilder {
io_interface::VERY_VERBOSE,
);
- pool
+ Ok(pool)
}
}
diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
index 18c8d01..7cba910 100644
--- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
@@ -209,8 +209,7 @@ impl PoolOptimizer {
pool.get_unacceptable_fixed_or_locked_packages().clone(),
removed_versions,
self.removed_versions_by_package.clone(),
- // TODO(phase-b): PartialSecurityAdvisory is a PHP class (no Clone). Need shared ownership rework.
- todo!("pool.get_all_security_removed_package_versions().clone()"),
+ pool.get_all_security_removed_package_versions().clone(),
pool.get_all_abandoned_removed_package_versions().clone(),
)
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
index fece1e4..5979f63 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
@@ -309,9 +309,11 @@ impl RuleSetGenerator {
for package in request.get_fixed_packages().values() {
if package.get_id() == -1 {
// fixed package was not added to the pool as it did not pass the stability requirements, this is fine
- // TODO(phase-c): wire Pool::is_unacceptable_fixed_or_locked_package(package) here;
- // the package handle and the pool's identity check are now both handle-based.
- if todo!("is_unacceptable_fixed_or_locked_package with a request package handle") {
+ if self
+ .pool
+ .borrow()
+ .is_unacceptable_fixed_or_locked_package(package.clone())
+ {
continue;
}
diff --git a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
index ec224b4..3136ce5 100644
--- a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
+++ b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
@@ -2,12 +2,14 @@
use crate::advisory::AuditConfig;
use crate::advisory::Auditor;
-use crate::advisory::PartialSecurityAdvisory;
+use crate::advisory::PartialOrFullSecurityAdvisory;
use crate::dependency_resolver::Pool;
use crate::dependency_resolver::Request;
use crate::package::BasePackageHandle;
+use crate::repository::PlatformRepository;
+use crate::repository::RepositoryInterfaceHandle;
+use crate::repository::RepositorySet;
use indexmap::IndexMap;
-use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
#[derive(Debug)]
@@ -27,37 +29,128 @@ impl SecurityAdvisoryPoolFilter {
pub fn filter(
&self,
pool: Pool,
- repositories: Vec<crate::repository::RepositoryInterfaceHandle>,
+ repositories: Vec<RepositoryInterfaceHandle>,
request: &Request,
- ) -> Pool {
- // TODO(phase-c): port the filter() body. Blockers:
- // * RepositorySet::new takes 6 args; ConfigSourceInterface refactor pending
- // * pool.get_packages() yields BasePackageHandle; widen to PackageInterfaceHandle
- // (via .into()) where the audit/repo APIs expect PackageInterface.
- // * Pool::new requires owned Vecs; clone the handles out of the existing pool.
- // * advisory map element type mismatch (PhpMixed vs PartialSecurityAdvisory).
- let _ = (
- pool,
- repositories,
- request,
- &self.auditor,
- &self.audit_config,
+ ) -> anyhow::Result<Pool> {
+ if !self.audit_config.block_insecure {
+ return Ok(pool);
+ }
+
+ let mut repo_set = RepositorySet::new(
+ "stable",
+ IndexMap::new(),
+ vec![],
+ IndexMap::new(),
+ IndexMap::new(),
+ IndexMap::new(),
);
- todo!("port SecurityAdvisoryPoolFilter::filter")
+ for repo in repositories {
+ repo_set.add_repository(repo)?;
+ }
+
+ let mut packages_for_advisories: Vec<BasePackageHandle> = vec![];
+ for package in pool.get_packages() {
+ if package.as_root().is_none()
+ && !PlatformRepository::is_platform_package(&package.get_name())
+ && !request.is_locked_package(package.clone())
+ {
+ packages_for_advisories.push(package.clone());
+ }
+ }
+
+ let mut all_advisories = repo_set.get_matching_security_advisories(
+ packages_for_advisories.clone(),
+ true,
+ true,
+ )?;
+ if self.auditor.needs_complete_advisory_load(
+ &all_advisories.advisories,
+ &self.audit_config.ignore_list_for_blocking,
+ ) {
+ all_advisories = repo_set.get_matching_security_advisories(
+ packages_for_advisories.clone(),
+ false,
+ true,
+ )?;
+ }
+
+ let advisory_map = self
+ .auditor
+ .process_advisories(
+ all_advisories.advisories,
+ &self.audit_config.ignore_list_for_blocking,
+ &self.audit_config.ignore_severity_for_blocking,
+ )
+ .advisories;
+
+ let mut packages: Vec<BasePackageHandle> = vec![];
+ let mut security_removed_versions: IndexMap<
+ String,
+ IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>,
+ > = IndexMap::new();
+ let mut abandoned_removed_versions: IndexMap<String, IndexMap<String, String>> =
+ IndexMap::new();
+ for package in pool.get_packages() {
+ if self.audit_config.block_abandoned
+ && self
+ .auditor
+ .filter_abandoned_packages(
+ &[package.clone()],
+ &self.audit_config.ignore_abandoned_for_blocking,
+ )?
+ .len()
+ != 0
+ {
+ for package_name in package.get_names(false) {
+ abandoned_removed_versions
+ .entry(package_name)
+ .or_default()
+ .insert(
+ package.get_version().to_string(),
+ package.get_pretty_version().to_string(),
+ );
+ }
+ continue;
+ }
+
+ let matching_advisories = self.get_matching_advisories(package.clone(), &advisory_map);
+ if matching_advisories.len() > 0 {
+ for package_name in package.get_names(false) {
+ security_removed_versions
+ .entry(package_name)
+ .or_default()
+ .insert(
+ package.get_version().to_string(),
+ matching_advisories.clone(),
+ );
+ }
+
+ continue;
+ }
+
+ packages.push(package.clone());
+ }
+
+ Ok(Pool::new(
+ packages,
+ pool.get_unacceptable_fixed_or_locked_packages().clone(),
+ pool.get_all_removed_versions().clone(),
+ pool.get_all_removed_versions_by_package().clone(),
+ security_removed_versions,
+ abandoned_removed_versions,
+ ))
}
- /// @param array<string, array<PartialSecurityAdvisory|SecurityAdvisory>> $advisoryMap
- /// @return list<PartialSecurityAdvisory|SecurityAdvisory>
fn get_matching_advisories(
&self,
package: BasePackageHandle,
- advisory_map: &IndexMap<String, Vec<PartialSecurityAdvisory>>,
- ) -> Vec<PartialSecurityAdvisory> {
+ advisory_map: &IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>,
+ ) -> Vec<PartialOrFullSecurityAdvisory> {
if package.is_dev() {
return vec![];
}
- let mut matching_advisories: Vec<PartialSecurityAdvisory> = vec![];
+ let mut matching_advisories: Vec<PartialOrFullSecurityAdvisory> = vec![];
for package_name in package.get_names(false) {
if !advisory_map.contains_key(&package_name) {
continue;
@@ -67,10 +160,8 @@ impl SecurityAdvisoryPoolFilter {
SimpleConstraint::new("==".to_string(), package.get_version().to_string(), None)
.into();
for advisory in &advisory_map[&package_name] {
- // advisory is PartialSecurityAdvisory or SecurityAdvisory; both have affected_versions: Box<dyn ConstraintInterface>
- if advisory.affected_versions.matches(&package_constraint) {
- // TODO(phase-b): PartialSecurityAdvisory is not Clone; replace with Rc when sharing is needed
- matching_advisories.push(todo!("clone PartialSecurityAdvisory"));
+ if advisory.affected_versions().matches(&package_constraint) {
+ matching_advisories.push(advisory.clone());
}
}
}