use wafrift_encoding::contextual::escape_for_context;
use wafrift_types::injection_context::InjectionContext;
#[test]
fn xml_attribute_escapes_apostrophe() {
let escaped = escape_for_context("don't", InjectionContext::XmlAttribute).unwrap();
assert!(
!escaped.contains('\''),
"single-quote must be escaped to ', got: {escaped}"
);
assert!(escaped.contains("'"), "expected ' in {escaped}");
}
#[test]
fn xml_attribute_still_escapes_other_metas() {
let escaped =
escape_for_context("a&b\"c<d>e", InjectionContext::XmlAttribute).unwrap();
assert!(escaped.contains("&"));
assert!(escaped.contains("""));
assert!(escaped.contains("<"));
assert!(escaped.contains(">"));
}
#[test]
fn json_string_escapes_line_separator_u2028() {
let payload = "a\u{2028}b";
let escaped = escape_for_context(payload, InjectionContext::JsonString).unwrap();
assert!(
!escaped.contains('\u{2028}'),
"U+2028 must be escaped, got: {escaped:?}"
);
assert!(escaped.contains("\\u2028"));
}
#[test]
fn json_string_escapes_paragraph_separator_u2029() {
let payload = "a\u{2029}b";
let escaped = escape_for_context(payload, InjectionContext::JsonString).unwrap();
assert!(
!escaped.contains('\u{2029}'),
"U+2029 must be escaped, got: {escaped:?}"
);
assert!(escaped.contains("\\u2029"));
}
#[test]
fn json_string_existing_escapes_still_work() {
let payload = "\"hello\\\nworld\t\x00";
let escaped = escape_for_context(payload, InjectionContext::JsonString).unwrap();
assert!(escaped.contains("\\\""));
assert!(escaped.contains("\\\\"));
assert!(escaped.contains("\\n"));
assert!(escaped.contains("\\t"));
assert!(escaped.contains("\\u0000"));
}
#[test]
fn cookie_value_encodes_space() {
let escaped = escape_for_context("hello world", InjectionContext::CookieValue).unwrap();
assert!(
!escaped.contains(' '),
"space must be percent-encoded in cookie value, got: {escaped}"
);
assert!(escaped.contains("%20"));
}
#[test]
fn cookie_value_encodes_comma() {
let escaped =
escape_for_context("a,b,c", InjectionContext::CookieValue).unwrap();
assert!(!escaped.contains(','), "comma must be encoded, got: {escaped}");
assert!(escaped.contains("%2C"));
}
#[test]
fn cookie_value_encodes_double_quote_and_backslash() {
let escaped =
escape_for_context("a\"b\\c", InjectionContext::CookieValue).unwrap();
assert!(
!escaped.contains('"'),
"double-quote must be encoded, got: {escaped}"
);
assert!(
!escaped.contains('\\'),
"backslash must be encoded, got: {escaped}"
);
assert!(escaped.contains("%22"));
assert!(escaped.contains("%5C"));
}
#[test]
fn cookie_value_still_encodes_pre_existing_set() {
let escaped =
escape_for_context("a;b=c\r\n\0d", InjectionContext::CookieValue).unwrap();
assert!(escaped.contains("%3B"));
assert!(escaped.contains("%3D"));
assert!(escaped.contains("%0D"));
assert!(escaped.contains("%0A"));
assert!(escaped.contains("%00"));
}