mod common;
use common::HIGH_ENTROPY_SECRET as S;
use velociredactor::{Allow, FormatHint, Redactor};
fn redact(format: &str, input: &str, comments: bool) -> String {
let redactor = Redactor::builder().comments(comments).build();
let redaction = redactor
.redact(input.as_bytes(), FormatHint::Name(format))
.unwrap_or_else(|e| panic!("redact as {format}: {e}"));
String::from_utf8(redaction.render(&Allow::none()).unwrap()).unwrap()
}
#[track_caller]
fn assert_comment_scanned(format: &str, input: &str, want: &str) {
assert_eq!(redact(format, input, false), input, "{format}: default");
let got = redact(format, input, true);
assert_eq!(got, want, "{format}: with comments");
assert_eq!(redact(format, &got, true), got, "{format}: not idempotent");
}
#[test]
fn json_line_and_block_comments() {
assert_comment_scanned(
"json",
&format!("{{\n // token {S}\n \"a\": \"ok\" /* and {S} */\n}}"),
"{\n // token REDACTION-1\n \"a\": \"ok\" /* and REDACTION-1 */\n}",
);
}
#[test]
fn json_strings_that_look_like_comments_are_left_alone() {
let input = format!(r#"{{"note": "// not a comment {S}"}}"#);
let want = r#"{"note": "// not a comment REDACTION-1"}"#;
assert_eq!(redact("json", &input, false), want);
assert_eq!(redact("json", &input, true), want);
}
#[test]
fn yaml_comments() {
assert_comment_scanned(
"yaml",
&format!("# lead {S}\na: ok # trail {S}\n"),
"# lead REDACTION-1\na: ok # trail REDACTION-1\n",
);
}
#[test]
fn yaml_hashes_inside_scalars_are_not_comments() {
let input = format!("note: |\n # inside {S}\nurl: \"http://x/#frag\"\n");
let want = "note: |\n # inside REDACTION-1\nurl: \"http://x/#frag\"\n";
assert_eq!(redact("yaml", &input, true), want);
assert_eq!(redact("yaml", &input, false), want);
}
#[test]
fn toml_comments() {
assert_comment_scanned(
"toml",
&format!("# lead {S}\n[s]\na = \"ok\" # trail {S}\n"),
"# lead REDACTION-1\n[s]\na = \"ok\" # trail REDACTION-1\n",
);
}
#[test]
fn toml_hashes_inside_strings_are_not_comments() {
let input = "a = \"x # y\"\nb = '''\n# z\n'''\n";
assert_eq!(redact("toml", input, true), input);
}
#[test]
fn hcl_comments() {
assert_comment_scanned(
"hcl",
&format!("# lead {S}\nvariable \"v\" {{\n default = \"ok\" // trail {S}\n}}\n"),
"# lead REDACTION-1\nvariable \"v\" {\n default = \"ok\" // trail REDACTION-1\n}\n",
);
}
#[test]
fn hcl_heredoc_bodies_are_values_not_comments() {
let input = format!("a = <<EOT\n# inside {S}\nEOT\n");
let want = "a = <<EOT\n# inside REDACTION-1\nEOT\n";
assert_eq!(redact("hcl", &input, true), want);
assert_eq!(redact("hcl", &input, false), want);
}
#[test]
fn ini_and_dotenv_comments() {
assert_comment_scanned(
"ini",
&format!("; lead {S}\n[s]\nkey = ok\n# other {S}\n"),
"; lead REDACTION-1\n[s]\nkey = ok\n# other REDACTION-1\n",
);
assert_comment_scanned(
"dotenv",
&format!("# lead {S}\nKEY=ok\n"),
"# lead REDACTION-1\nKEY=ok\n",
);
}
#[test]
fn xml_comments() {
assert_comment_scanned(
"xml",
&format!("<r><!-- token {S} --><a>ok</a></r>"),
"<r><!-- token REDACTION-1 --><a>ok</a></r>",
);
}
#[test]
fn properties_comments() {
assert_comment_scanned(
"properties",
&format!("# lead {S}\nkey=ok\n"),
"# lead REDACTION-1\nkey=ok\n",
);
}
#[test]
fn a_secret_in_a_comment_shares_the_token_with_the_same_value_elsewhere() {
let input = format!("# see {S}\na = \"{S}\"\n");
assert_eq!(
redact("toml", &input, true),
"# see REDACTION-1\na = \"REDACTION-1\"\n"
);
}
#[test]
fn formats_without_comments_are_unaffected() {
let input = format!("name,key\nx,{S}\n");
let with = redact("csv", &input, true);
assert_eq!(with, redact("csv", &input, false));
assert_eq!(with, "name,key\nx,REDACTION-1\n");
}