use regex::Regex;
use std::sync::LazyLock;
use crate::facts::shell::Argv;
#[expect(
clippy::expect_used,
reason = "static pattern literal validated by tests"
)]
pub static SENSITIVE_PATH: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(concat!(
r"(?x)",
r"(?:",
r"(?:~|\$HOME|\$\{HOME\})/(?i-u:\.ssh)(?:/|\b)",
r"|(?:~|\$HOME|\$\{HOME\})/(?i-u:\.aws)(?:/|\b)",
r"|(?:~|\$HOME|\$\{HOME\})/(?i-u:\.config/gcloud)(?:/|\b)",
r"|(?:~|\$HOME|\$\{HOME\})/(?i-u:\.kube/config)\b",
r"|(?:~|\$HOME|\$\{HOME\})/(?i-u:\.docker/config\.json)\b",
r"|\b(?i-u:id_(?:rsa|ed25519|ecdsa))\b",
r"|(?:^|/|\s|[*?\[\]=])(?i-u:\.env)(?:\.[A-Za-z0-9_-]+)?\b",
r"|\b(?i-u:\.npmrc)\b",
r"|\b(?i-u:\.pypirc)\b",
r"|\S+(?i-u:\.tfstate)\b",
r"|-----BEGIN\s+[A-Z\s]+PRIVATE\s+KEY-----",
r")",
))
.expect("SENSITIVE_PATH regex")
});
pub(super) fn argv_references_sensitive(argv: &Argv) -> bool {
if SENSITIVE_PATH.is_match(&argv.head) {
return true;
}
if argv.args.iter().any(|a| SENSITIVE_PATH.is_match(a)) {
return true;
}
argv.env_assignments
.iter()
.any(|e| SENSITIVE_PATH.is_match(&e.value))
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::LazyLock;
#[test]
fn all_regexes_compile() {
LazyLock::force(&SENSITIVE_PATH);
}
}