use std::path::{Path, PathBuf};
const FORBIDDEN: &[&str] = &[
"secret_texts",
"secret_bytes",
"secret_literals",
"secret_values",
"secret",
];
const ALLOWED: &[(&str, &str)] = &[(
"secret_tainted_paths",
"returns redacted dotted labels of the tainted cone, never secret bytes",
)];
fn rust_sources(root: &Path) -> Vec<PathBuf> {
let mut out = Vec::new();
let mut stack = vec![root.to_path_buf()];
while let Some(directory) = stack.pop() {
for entry in std::fs::read_dir(&directory).expect("src directory") {
let path = entry.expect("directory entry").path();
if path.is_dir() {
stack.push(path);
} else if path.extension().and_then(|ext| ext.to_str()) == Some("rs") {
out.push(path);
}
}
}
out.sort();
out
}
fn logical_lines(text: &str) -> Vec<(usize, String)> {
let lines: Vec<&str> = text.lines().collect();
let mut out = Vec::new();
let mut buffer = String::new();
let mut start = 0usize;
for (index, line) in lines.iter().enumerate() {
let trimmed = line.trim();
if buffer.is_empty() {
start = index + 1;
} else {
buffer.push(' ');
}
buffer.push_str(trimmed);
let balanced = buffer.matches('(').count() == buffer.matches(')').count();
let next_continues = lines.get(index + 1).is_some_and(|next| {
let next = next.trim();
next.starts_with("->") || next.starts_with("where")
});
if balanced && !next_continues {
out.push((start, std::mem::take(&mut buffer)));
}
}
if !buffer.is_empty() {
out.push((start, buffer));
}
out
}
fn public_fn_name(line: &str) -> Option<&str> {
let mut rest = line.strip_prefix("pub ")?;
loop {
let stripped = ["const ", "async ", "unsafe "]
.iter()
.find_map(|modifier| rest.strip_prefix(modifier));
match stripped {
Some(next) => rest = next,
None => break,
}
}
let rest = rest.strip_prefix("fn ")?;
Some(rest.split('(').next().unwrap_or("").trim())
}
fn returns_raw_text(line: &str) -> bool {
let Some(arrow) = line.rfind("->") else {
return false;
};
let tail = &line[arrow + 2..];
let signature = tail.split('{').next().unwrap_or(tail);
let signature = signature.split('}').next().unwrap_or(signature);
signature.contains("String") || signature.contains("u8")
}
#[test]
fn the_crate_exposes_no_plaintext_secret_accessor() {
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
let mut offenders = Vec::new();
for path in rust_sources(&root) {
let relative = path
.strip_prefix(env!("CARGO_MANIFEST_DIR"))
.unwrap_or(&path)
.display()
.to_string();
let text = std::fs::read_to_string(&path).expect("source file");
for (line_number, line) in logical_lines(&text) {
if line.starts_with("//") {
continue;
}
if let Some(name) = public_fn_name(&line) {
if FORBIDDEN.contains(&name) {
offenders.push(format!("{relative}:{line_number}: {line}"));
continue;
}
if name.contains("secret") {
let allowed = ALLOWED.iter().any(|(allowed, _)| *allowed == name);
if !allowed && returns_raw_text(&line) {
offenders.push(format!("{relative}:{line_number}: {line}"));
}
}
}
if line.starts_with("pub use") {
for forbidden in FORBIDDEN {
if line
.split(|c: char| !c.is_alphanumeric() && c != '_')
.any(|token| token == *forbidden)
{
offenders.push(format!("{relative}:{line_number}: {line}"));
}
}
}
}
}
assert!(
offenders.is_empty(),
"the crate must not expose secret plaintext; found:\n{}",
offenders.join("\n")
);
}
#[test]
fn the_redaction_marker_is_the_only_public_secret_constant() {
assert_eq!(active_infinity::interop::SECRET_MARKER, "***SECRET***");
}
#[test]
fn the_allowlist_entries_still_exist_and_are_argued() {
let interop =
std::fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join("src/interop.rs"))
.expect("source file");
for (name, reason) in ALLOWED {
assert!(
interop.contains(&format!("pub fn {name}")),
"{name} is allowlisted but no longer exists; remove the entry"
);
assert!(
reason.len() > 20,
"{name} needs a real justification for the allowlist"
);
}
}