Skip to main content

DependencyVulnerabilities

Struct DependencyVulnerabilities 

Source
pub struct DependencyVulnerabilities {
    pub advisories: Capped<Arc<Advisory>>,
    pub upgrade_status: UpgradeStatus,
    pub fix_target_status: UpgradeStatus,
}
Expand description

Vulnerability data for one dependency that OSV reported as non-clean.

Fields§

§advisories: Capped<Arc<Advisory>>

Advisories fetched in full, capped at crate::osv::ADVISORY_DISPLAY_CAP (invariant 3 in architecture.md §8: the fetch itself is capped, not only the render) — the total advisory count OSV reported is carried alongside via Capped::total, independent of how many were actually fetched, and is the source of the render layer’s “+N more advisories” count (architecture.md §7/§8 invariant 3).

§upgrade_status: UpgradeStatus

Result of phase B’s “latest” check, if it has run for this dependency.

§fix_target_status: UpgradeStatus

Independent verification of Self::recommended_fix’s target version F, if F differs from the “latest” candidate upgrade_status already covers. Left at UpgradeStatus::NotChecked until Self::recommended_fix has been computed and F’s status resolved — either reused from upgrade_status when F equals latest, or checked live via crate::osv::OsvClient::check_candidates otherwise (always live-checked when F differs from latest: a data-derived shortcut was tried and rejected — see git history on this field and #462’s critique — because it degenerates into checking F against exactly the advisories it was computed from, proving nothing about an advisory phase A never fetched at all, which is the actual gap #462 closes). See run_osv_phase_b_and_commit in deps-lsp for the resolution order.

A caller must not treat a bare UpgradeStatus::CandidateClean check as the only valid “verified” state: UpgradeStatus::CandidateVulnerable can also be a legitimate, presentable fix when every reported id is an advisory Self::recommended_fix already declined to claim (excluded via still_applying, or never had a known fix) — see deps-core’s lsp_helpers::code_actions::fix_target_is_verified (the actual gate generate_code_actions uses) for the full contract, rather than re-deriving it ad hoc.

Implementations§

Source§

impl DependencyVulnerabilities

Source

pub fn recommended_fix(&self) -> Option<FixRecommendation>

Recommends a single upgrade target that resolves as many of this dependency’s known advisories as possible.

advisory_ids is computed first: every advisory with a known fix, minus — when phase B (UpgradeStatus::CandidateVulnerable) reports that some ids still apply to the checked candidate — those ids, since claiming a fix for them would be false. version is then the highest Advisory::fixed_versions entry across only the remaining claimed advisories, not every advisory: computing it over the full set first would let an advisory this method just excluded (because its own fix is known not to hold) drag the recommendation past a lower version that already clears everything actually being claimed. Returns None when no advisory has a claimable fix.

The subtraction’s premise is that the checked candidate is at least as new as version; when phase B checked an older candidate the subtraction is merely over-conservative (it only ever removes claims), so this is documented rather than guarded against.

§Limitations

advisories is capped at fetch time (crate::osv::ADVISORY_DISPLAY_CAP), so version is the max over a possibly incomplete subset — the “+N more advisories” hint already signals that incompleteness, so this is an accepted under-report, not a bug. Advisory also retains only fixed_versions, never introduced events, so a version reintroduced above its own last known fix (and not yet re-fixed) can still be claimed as a fix whenever phase B has not run for this dependency (UpgradeStatus::NotChecked) — the post-edit rescan is what surfaces that case.

§Examples
use deps_core::osv::{Advisory, Capped, DependencyVulnerabilities, UpgradeStatus, VulnSeverity};
use std::sync::Arc;

fn advisory(id: &str, fixed: &str) -> Arc<Advisory> {
    Arc::new(Advisory {
        id: id.to_string(),
        modified: "2023-01-01T00:00:00Z".to_string(),
        summary: None,
        aliases: vec![],
        severity: VulnSeverity::High,
        cvss_vector: None,
        fixed_versions: vec![fixed.to_string()],
        url: String::new(),
    })
}

let dv = DependencyVulnerabilities {
    advisories: Capped::new(vec![advisory("RUSTSEC-1", "1.2.0")], 1),
    upgrade_status: UpgradeStatus::NotChecked,
    fix_target_status: UpgradeStatus::NotChecked,
};

let fix = dv.recommended_fix().unwrap();
assert_eq!(fix.version, "1.2.0");
assert_eq!(fix.advisory_ids, vec!["RUSTSEC-1".to_string()]);

Trait Implementations§

Source§

impl Clone for DependencyVulnerabilities

Source§

fn clone(&self) -> DependencyVulnerabilities

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DependencyVulnerabilities

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more