xbp-analysis 10.57.0

Language-agnostic static analysis (error-handling / Aspirator-style) for XBP
Documentation
use super::{base_caps, concepts_of, finding_from_concept};
use crate::domain::concepts::ConceptKind;
use crate::domain::model::LanguageModel;
use crate::domain::rule::{Rule, RuleMeta};
use crate::domain::types::{Confidence, Finding, Severity};
use std::sync::OnceLock;

#[derive(Default)]
pub struct UnsafeTerminationRule;

impl Rule for UnsafeTerminationRule {
    fn meta(&self) -> &RuleMeta {
        static META: OnceLock<RuleMeta> = OnceLock::new();
        META.get_or_init(|| RuleMeta {
            id: "unsafe-termination".into(),
            name: "Unsafe termination".into(),
            description: "Process or task may abort on recoverable errors (unwrap/expect/panic)."
                .into(),
            default_severity: Severity::High,
            required_capabilities: base_caps(),
            autofix_safe: false,
        })
    }

    fn evaluate(&self, model: &LanguageModel) -> Vec<Finding> {
        concepts_of(model, ConceptKind::Termination)
            .map(|(lang, c)| {
                let confidence = if c.tag == "unwrap" || c.tag == "expect" || c.tag == "panic" {
                    Confidence::High
                } else {
                    Confidence::Medium
                };
                finding_from_concept(
                    &self.meta().id,
                    lang,
                    c,
                    Severity::High,
                    confidence,
                    format!("Unsafe termination via `{}`.", c.tag),
                    "A recoverable error aborts the process or task, taking down the service.",
                    "Return Result/Option, use map_err, or handle with explicit recovery.",
                )
            })
            .collect()
    }
}