{"record":{"id":"6de3b8d744f89be1","repo":"stamparm/maltrail","slug":"aho-corasick-build","errorCode":null,"errorMessage":"aho-corasick build","messagePattern":"aho-corasick build","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/settings.rs","lineNumber":243,"sourceCode":"/// `\\A\\d+\\-\\d+\\-\\d+\\-\\d+\\Z`, hand-coded — the dashed-quad first label check.\n#[inline]\npub fn is_dashed_quad(label: &str) -> bool {\n    let mut groups = 0;\n    for part in label.split('-') {\n        if part.is_empty() || !part.bytes().all(|c| c.is_ascii_digit()) {\n            return false;\n        }\n        groups += 1;\n    }\n    groups == 4\n}\n\npub fn statics() -> &'static Statics {\n    STATICS.get().expect(\"settings::init() must run before statics()\")\n}\n\nfn ac(patterns: &[&str]) -> AhoCorasick {\n    AhoCorasick::new(patterns).expect(\"aho-corasick build\")\n}\n\n/// `ac()` for patterns that have to match regardless of case, which is how HTTP header names\n/// arrive on the wire.\nfn ac_nocase(patterns: &[&str]) -> AhoCorasick {\n    aho_corasick::AhoCorasickBuilder::new().ascii_case_insensitive(true).build(patterns).expect(\"aho-corasick build\")\n}\n\nimpl Statics {\n    pub fn build(root: PathBuf) -> Statics {\n        let ua_src = build_suspicious_ua_regex(&root);\n        let suspicious_ua = match pyre::build(&ua_src) {\n            Ok(re) => Some(re),\n            Err(e) => {\n                crate::ceprintln!(\"[!] unable to compile SUSPICIOUS_UA_REGEX ({e}); user-agent heuristic disabled\");\n                None\n            }\n        };","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/settings.rs#L225-L261","documentation":"The settings module builds Aho-Corasick automata for pre-condition pattern matching via ac(), which panics with \"aho-corasick build\" if AhoCorasick::new(patterns) returns an Err. The aho-corasick library only fails construction in rare cases (e.g. the match kind or pattern set is not representable, or pattern limits are exceeded), so this expect is an internal-invariant assertion: Statics::build cannot proceed without the automaton.","triggerScenarios":"Statics::build() calls ac(SUSPICIOUS_HTTP_REQUEST_PRE_CONDITION), ac(SUSPICIOUS_PROXY_PROBE_PRE_CONDITION), ac(WHITELIST_HTTP_REQUEST_PATHS) or ac(WHITELIST_DIRECT_DOWNLOAD_KEYWORDS) and AhoCorasick::new returns Err (empty/invalid pattern configuration or aho-corasick build limitation for the given MatchKind).","commonSituations":"Shipping a pattern list constant that is malformed for the builder configuration; upgrading aho-corasick to a version with stricter construction rules; accidentally passing an empty slice where the automaton kind requires patterns.","solutions":["Inspect the pattern constants passed to ac() (SUSPICIOUS_HTTP_REQUEST_PRE_CONDITION etc.) for entries incompatible with the builder configuration","Print/return the underlying aho_corasick::Error instead of expect to see the real cause","Pin or update the aho-corasick dependency to a version compatible with the pattern set","If an empty pattern list is legitimate, construct with AhoCorasickBuilder and handle the empty case explicitly"],"exampleFix":"// before\nfn ac(patterns: &[&str]) -> AhoCorasick {\n    AhoCorasick::new(patterns).expect(\"aho-corasick build\")\n}\n// after\nfn ac(patterns: &[&str]) -> AhoCorasick {\n    AhoCorasick::new(patterns).unwrap_or_else(|e| panic!(\"aho-corasick build failed for {:?}: {e}\", patterns))\n}","handlingStrategy":"validation","validationCode":"assert!(!patterns.is_empty(), \"ac() pattern list must not be empty\");","typeGuard":"fn valid_patterns(patterns: &[&str]) -> bool { !patterns.is_empty() && patterns.iter().all(|p| !p.is_empty()) }","tryCatchPattern":"let automaton = AhoCorasick::new(patterns).unwrap_or_else(|e| panic!(\"aho-corasick build: {e}\"));","preventionTips":["Keep pattern constants non-empty and reviewed","Pin aho-corasick versions and read changelogs before upgrading","Return the underlying error in panic messages for diagnosability"],"tags":["rust","aho-corasick","panic","initialization"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}