use gotmpl::html::{HTML, Template};
use gotmpl::tmap;
fn main() {
let src = r#"<p>{{.Comment}}</p>
<a href="{{.Link}}">link</a>
<p class="{{.Cls}}">
<script>var s = "{{.Comment}}";</script>
<p>trusted: {{.Trusted}}</p>"#;
let data = tmap! {
"Comment" => "<script>alert('xss')</script>",
"Link" => "javascript:alert(document.cookie)",
"Cls" => "\"><img src=x onerror=alert(1)>",
"Trusted" => HTML::from("<em>hand-written & safe</em>"),
};
let out = Template::new("page")
.parse(src)
.expect("parse")
.execute_to_string(&data)
.expect("execute");
println!("--- rendered (safely escaped) ---\n{out}\n");
assert!(
out.contains("<script>alert('xss')</script>"),
"HTML text context escapes the script tag"
);
assert!(
out.contains(r##"href="#ZgotmplZ""##),
"javascript: URL is filtered to #ZgotmplZ"
);
assert!(
!out.contains("<img src=x onerror"),
"attribute-breakout payload cannot start a real tag"
);
assert!(
out.contains("<em>hand-written & safe</em>"),
"html::HTML content is emitted unescaped"
);
println!("All escaping assertions passed \u{2713}");
}