html_escape/lib.rs
1use std::cmp::max;
2
3pub fn escape(src: &str) -> String {
4 let mut ret_val = String::with_capacity(max(4, src.len()));
5 for c in src.chars() {
6 let replacement = match c {
7 // this character, when confronted, will start a tag
8 '<' => "<",
9 // in an unquoted attribute, will end the attribute value
10 '>' => ">",
11 // in an attribute surrounded by double quotes, this character will end the attribute value
12 '\"' => """,
13 // in an attribute surrounded by single quotes, this character will end the attribute value
14 '\'' => "'",
15 // in HTML5, returns a bogus parse error in an unquoted attribute, while in SGML/HTML, it will end an attribute value surrounded by backquotes
16 '`' => "`",
17 // in an unquoted attribute, this character will end the attribute
18 '/' => "/",
19 // starts an entity reference
20 '&' => "&",
21 // if at the beginning of an unquoted attribute, will get ignored
22 '=' => "=",
23 // will end an unquoted attribute
24 ' ' => " ",
25 '\t' => "	",
26 '\n' => " ",
27 '\x0c' => "",
28 '\r' => " ",
29 // a spec-compliant browser will perform this replacement anyway, but the middleware might not
30 '\0' => "�",
31 // ALL OTHER CHARACTERS ARE PASSED THROUGH VERBATIM
32 _ => {
33 ret_val.push(c);
34 continue;
35 }
36 };
37 ret_val.push_str(replacement);
38 }
39 ret_val
40}