#[must_use]
pub(crate) fn references_dotenv_file(lower: &str) -> bool {
if lower.contains("dotenv") || lower.contains("load_dotenv") {
return true;
}
let mut search_start = 0;
while let Some(rel) = lower[search_start..].find(".env") {
let abs = search_start + rel;
let after = abs + ".env".len();
let next = lower[after..].chars().next();
let is_terminator = match next {
None => true,
Some(c) => matches!(
c,
'"' | '\'' | ' ' | '\t' | '\n' | '\r' | ':' | ',' | ')' | ';' | '`' | '.'
),
};
if is_terminator {
let before = lower[..abs].chars().next_back();
let before_ok = matches!(
before,
None | Some(
'"' | '\'' | '/' | '\\' | ' ' | '\t' | '(' | ',' | ':' | '`' | '=' | '-'
)
);
if before_ok {
return true;
}
}
search_start = abs + 1;
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rejects_lookalike_filenames() {
for sample in [
"source .envrc",
"cat .envelope",
"open(.environments/prod.conf)",
"let v = MY.ENV;",
"value = some.envoy.config",
"read .envoy_config",
] {
assert!(
!references_dotenv_file(&sample.to_ascii_lowercase()),
"must not match lookalike: {sample}"
);
}
}
#[test]
fn fires_on_genuine_dotenv_references() {
for sample in [
"cat .env",
"open(\".env\")",
"fs.readFileSync('.env')",
"VALUE=$(cat .env)",
"from dotenv import load_dotenv",
"require('dotenv').config()",
"cat /etc/secrets/.env",
"read .env",
] {
assert!(
references_dotenv_file(&sample.to_ascii_lowercase()),
"must match genuine reference: {sample}"
);
}
}
#[test]
fn fires_on_dotenv_variant_files() {
for sample in [
"cat .env.local",
"cat .env.production",
"cat .env.staging",
"cat .env.development",
"cat .env.test",
"fs.readFileSync('.env.local')",
"open(\".env.production\")",
] {
assert!(
references_dotenv_file(&sample.to_ascii_lowercase()),
"must match dotenv variant: {sample}"
);
}
assert!(
!references_dotenv_file("cat .environment"),
"must not match .environment"
);
}
}