#[cfg(feature = "sanitize")]
pub(crate) fn sanitize_html(html: &str) -> String {
ammonia::Builder::default()
.add_generic_attributes(["id", "class"])
.clean(html)
.to_string()
}
#[cfg(not(feature = "sanitize"))]
pub(crate) fn sanitize_html(html: &str) -> String {
html.to_string()
}
#[cfg(all(test, feature = "sanitize"))]
mod tests {
use super::*;
#[test]
fn strips_script_tags() {
let dirty = "<p>hi</p><script>alert(1)</script>";
assert_eq!(sanitize_html(dirty), "<p>hi</p>");
}
#[test]
fn strips_event_handler_attributes() {
let dirty = r#"<img src="x" onerror="alert(1)">"#;
let clean = sanitize_html(dirty);
assert!(!clean.contains("onerror"));
}
#[test]
fn preserves_id_attribute_on_headings() {
let html = r#"<h2 id="getting-started">Getting Started</h2>"#;
assert_eq!(sanitize_html(html), html);
}
#[test]
fn preserves_class_attribute() {
let html = r#"<ol class="footnotes"><li class="footnote">a</li></ol>"#;
assert_eq!(sanitize_html(html), html);
}
#[test]
fn still_strips_script_bearing_attributes_from_a_classed_element() {
let dirty = r#"<p class="note" onclick="alert(1)">hi</p>"#;
let clean = sanitize_html(dirty);
assert!(clean.contains(r#"class="note""#));
assert!(
!clean.contains("onclick"),
"event handler survived: {clean}"
);
}
}