/// HTML/Script 内容清理工具。 /// /// 在用户输入进入数据库之前,剥离所有 HTML 标签,防止存储型 XSS。 /// 覆盖场景:用户名、显示名、邮箱、电话等字符串字段。 /// 剥离字符串中的所有 HTML 标签,返回纯文本。 /// /// ```rust /// use erp_core::sanitize::strip_html_tags; /// assert_eq!(strip_html_tags(""), "alert(1)"); /// assert_eq!(strip_html_tags(""), ""); /// assert_eq!(strip_html_tags("Hello World"), "Hello World"); /// ``` pub fn strip_html_tags(input: &str) -> String { let mut result = String::with_capacity(input.len()); let mut in_tag = false; let mut depth = 0usize; for ch in input.chars() { match ch { '<' => { in_tag = true; depth += 1; } '>' => { if depth > 0 { depth -= 1; } if depth == 0 { in_tag = false; } } _ => { if !in_tag { result.push(ch); } } } } result.trim().to_string() } /// 对 Option 类型的字段进行清理。 pub fn sanitize_option(input: Option) -> Option { input.map(|s| strip_html_tags(&s)).filter(|s| !s.is_empty()) } /// 对 String 类型的必填字段进行清理。 pub fn sanitize_string(input: &str) -> String { strip_html_tags(input) } #[cfg(test)] mod tests { use super::*; #[test] fn strips_script_tag() { assert_eq!(strip_html_tags(""), "alert('xss')"); } #[test] fn strips_img_onerror() { assert_eq!(strip_html_tags(""), ""); } #[test] fn strips_bold_tags() { assert_eq!(strip_html_tags("Hello World"), "Hello World"); } #[test] fn no_tags_passthrough() { assert_eq!(strip_html_tags("Normal text"), "Normal text"); } #[test] fn nested_tags() { assert_eq!(strip_html_tags("

text

"), "text"); } #[test] fn sanitize_option_some() { assert_eq!( sanitize_option(Some("".to_string())), Some("evil".to_string()) ); } #[test] fn sanitize_option_none() { assert_eq!(sanitize_option(None), None); } #[test] fn sanitize_option_becomes_empty() { assert_eq!(sanitize_option(Some("".to_string())), None); } }