50 lines
1.6 KiB
Rust
50 lines
1.6 KiB
Rust
use std::sync::LazyLock;
|
|
|
|
static REDACT_REGEX: LazyLock<regex::Regex> = LazyLock::new(|| {
|
|
regex::Regex::new(r#"([A-Z_][A-Z0-9_]*)=("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S+)"#).unwrap()
|
|
});
|
|
|
|
/// Whether a given environment variable name should have its value redacted
|
|
pub fn should_redact(env_var_name: &str) -> bool {
|
|
const REDACTED_SUFFIXES: &[&str] = &[
|
|
"KEY",
|
|
"TOKEN",
|
|
"PASSWORD",
|
|
"SECRET",
|
|
"PASS",
|
|
"CREDENTIALS",
|
|
"LICENSE",
|
|
];
|
|
REDACTED_SUFFIXES
|
|
.iter()
|
|
.any(|suffix| env_var_name.ends_with(suffix))
|
|
}
|
|
|
|
/// Redact a string which could include a command with environment variables
|
|
pub fn redact_command(command: &str) -> String {
|
|
REDACT_REGEX
|
|
.replace_all(command, |caps: ®ex::Captures| {
|
|
let var_name = &caps[1];
|
|
let value = &caps[2];
|
|
if should_redact(var_name) {
|
|
format!(r#"{}="[REDACTED]""#, var_name)
|
|
} else {
|
|
format!("{}={}", var_name, value)
|
|
}
|
|
})
|
|
.to_string()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_redact_string_with_multiple_env_vars() {
|
|
let input = r#"failed to spawn command cd "/code/something" && ANTHROPIC_API_KEY="sk-ant-api03-WOOOO" COMMAND_MODE="unix2003" GEMINI_API_KEY="AIGEMINIFACE" HOME="/Users/foo""#;
|
|
let result = redact_command(input);
|
|
let expected = r#"failed to spawn command cd "/code/something" && ANTHROPIC_API_KEY="[REDACTED]" COMMAND_MODE="unix2003" GEMINI_API_KEY="[REDACTED]" HOME="/Users/foo""#;
|
|
assert_eq!(result, expected);
|
|
}
|
|
}
|