pub fn for_html_attribute(input: &str) -> StringExpand description
encodes input for safe embedding in a quoted HTML attribute value.
this encoder does not encode > (harmless inside quoted attributes)
and is slightly more minimal than for_html. it encodes both " and
' so the output is safe regardless of which quote delimiter is used.
not safe for unquoted attributes — use for_html_unquoted_attribute
for that context.
§encoded characters
| input | output |
|---|---|
& | & |
< | < |
" | " |
' | ' |
invalid XML characters are replaced with a space.
§examples
use contextual_encoder::for_html_attribute;
// safe for both quote styles
assert_eq!(
for_html_attribute(r#"it's a "test""#),
"it's a "test""
);
// > is not encoded
assert_eq!(for_html_attribute("a > b"), "a > b");Examples found in repository?
examples/contexts.rs (line 41)
18fn main() {
19 let input = r#"<script>alert("xss")</script>"#;
20
21 println!("input: {input}");
22 println!();
23
24 // -----------------------------------------------------------------------
25 // comparison: same input across all encoders
26 // -----------------------------------------------------------------------
27
28 // html text content AND quoted attributes (safe default when unsure)
29 println!("--- html ---");
30 println!(" for_html: {}", for_html(input));
31
32 // html text nodes only — does NOT encode quotes, so never use in attributes
33 println!(
34 " for_html_content: {}",
35 for_html_content(input)
36 );
37
38 // quoted attribute values only — does NOT encode >, slightly more minimal
39 println!(
40 " for_html_attribute: {}",
41 for_html_attribute(input)
42 );
43
44 // unquoted attribute values — most aggressive, encodes whitespace/grave/etc.
45 println!(
46 " for_html_unquoted_attribute: {}",
47 for_html_unquoted_attribute(input)
48 );
49 println!();
50
51 // universal js encoder — safe in event attrs, <script> blocks, and .js files
52 println!("--- javascript ---");
53 println!(" for_javascript: {}", for_javascript(input));
54
55 // html event attributes (onclick="...") — does not escape /
56 println!(
57 " for_javascript_attribute: {}",
58 for_javascript_attribute(input)
59 );
60
61 // <script> blocks — uses \" and \' (not safe in html attributes)
62 println!(
63 " for_javascript_block: {}",
64 for_javascript_block(input)
65 );
66
67 // standalone .js files — minimal, NOT safe in any html context
68 println!(
69 " for_javascript_source: {}",
70 for_javascript_source(input)
71 );
72
73 // ES6 template literals (`...`) — escapes backtick and ${} interpolation
74 let template_input = r#"`Hello ${name}`, welcome</script>"#;
75 println!(
76 " for_js_template: {}",
77 for_js_template(template_input)
78 );
79 println!();
80
81 // quoted css string values, e.g., content: "..." or font-family: "..."
82 println!("--- css ---");
83 println!(" for_css_string: {}", for_css_string(input));
84
85 // css url() values, quoted or unquoted — like for_css_string plus space
86 println!(" for_css_url: {}", for_css_url(input));
87 println!();
88
89 // uri component (query params, path segments) — NOT for full urls
90 println!("--- uri ---");
91 println!(
92 " for_uri_component: {}",
93 for_uri_component(input)
94 );
95
96 // form-urlencoded value (WHATWG) — space→+, different safe set from RFC 3986
97 println!(
98 " for_form_urlencoded: {}",
99 for_form_urlencoded(input)
100 );
101 println!();
102
103 // xml 1.0 aliases — identical to the html encoders
104 println!("--- xml 1.0 ---");
105 println!(" for_xml: {}", for_xml(input));
106 println!(" for_xml_content: {}", for_xml_content(input));
107 println!(
108 " for_xml_attribute: {}",
109 for_xml_attribute(input)
110 );
111
112 // xml-only contexts
113 println!(" for_xml_comment: {}", for_xml_comment(input));
114 println!(" for_cdata: {}", for_cdata(input));
115 println!();
116
117 // xml 1.1 — restricted chars get &#xHH; instead of space
118 println!("--- xml 1.1 ---");
119 let xml11_input = "a\x01b<c>";
120 println!(" for_xml11: {}", for_xml11(xml11_input));
121 println!(
122 " for_xml11_content: {}",
123 for_xml11_content(xml11_input)
124 );
125 println!(
126 " for_xml11_attribute: {}",
127 for_xml11_attribute(xml11_input)
128 );
129 println!();
130
131 // rust literals — \xHH escapes, UTF-8 byte encoding for byte strings
132 println!("--- rust ---");
133 println!(" for_rust_string: {}", for_rust_string(input));
134 println!(
135 " for_rust_byte_string: {}",
136 for_rust_byte_string(input)
137 );
138 // unlike the others, this encoder takes exactly one character
139 println!(" for_rust_char(\"'\"): {}", for_rust_char("'"));
140 println!(
141 " for_rust_char_checked(input): {:?}",
142 for_rust_char_checked(input)
143 );
144 println!();
145
146 // json string value — \\uXXXX escapes for control chars and specials
147 println!("--- json ---");
148 println!(" for_json: {}", for_json(input));
149 println!();
150
151 // sql string literals — single-quote doubling (standard) or backslash escaping (mysql)
152 println!("--- sql ---");
153 println!(" for_sql: {}", for_sql(input));
154 println!(
155 " for_sql_backslash: {}",
156 for_sql_backslash(input)
157 );
158
159 // -----------------------------------------------------------------------
160 // practical: one realistic input per sink, correct encoder for each
161 // -----------------------------------------------------------------------
162
163 let user_name = r#"Bob <img src=x onerror="alert(1)">"#;
164 let user_query = "hello world & goodbye";
165 let user_text = r#"hi from </script><script>alert(1)</script>"#;
166 let user_css_text = r#"hello "css" \ test"#;
167
168 println!("--- practical usage ---");
169
170 // html text node — for_html_content is the right encoder
171 println!(r#" <p>{}</p>"#, for_html_content(user_name));
172
173 // nested context: uri component inside an html attribute.
174 // encode from inside out: first percent-encode the query value,
175 // then html-attribute-encode the entire href.
176 let href = format!("/search?q={}", for_uri_component(user_query));
177 println!(r#" <a href="{}">search</a>"#, for_html_attribute(&href),);
178
179 // actual css string context: a quoted content value in a stylesheet
180 println!(
181 r#" <style>.msg::after {{ content: "{}"; }}</style>"#,
182 for_css_string(user_css_text),
183 );
184
185 // javascript string inside an event-handler attribute
186 println!(
187 r#" <button onclick="greet('{}');">hi</button>"#,
188 for_javascript_attribute(user_text),
189 );
190}