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 42)
19fn main() {
20 let input = r#"<script>alert("xss")</script>"#;
21
22 println!("input: {input}");
23 println!();
24
25 // -----------------------------------------------------------------------
26 // comparison: same input across all encoders
27 // -----------------------------------------------------------------------
28
29 // html text content AND quoted attributes (safe default when unsure)
30 println!("--- html ---");
31 println!(" for_html: {}", for_html(input));
32
33 // html text nodes only — does NOT encode quotes, so never use in attributes
34 println!(
35 " for_html_content: {}",
36 for_html_content(input)
37 );
38
39 // quoted attribute values only — does NOT encode >, slightly more minimal
40 println!(
41 " for_html_attribute: {}",
42 for_html_attribute(input)
43 );
44
45 // unquoted attribute values — most aggressive, encodes whitespace/grave/etc.
46 println!(
47 " for_html_unquoted_attribute: {}",
48 for_html_unquoted_attribute(input)
49 );
50 println!();
51
52 // universal js encoder — safe in event attrs, <script> blocks, and .js files
53 println!("--- javascript ---");
54 println!(" for_javascript: {}", for_javascript(input));
55
56 // html event attributes (onclick="...") — does not escape /
57 println!(
58 " for_javascript_attribute: {}",
59 for_javascript_attribute(input)
60 );
61
62 // <script> blocks — uses \" and \' (not safe in html attributes)
63 println!(
64 " for_javascript_block: {}",
65 for_javascript_block(input)
66 );
67
68 // standalone .js / json files — minimal, NOT safe in any html context
69 println!(
70 " for_javascript_source: {}",
71 for_javascript_source(input)
72 );
73
74 // ES6 template literals (`...`) — escapes backtick and ${} interpolation
75 let template_input = r#"`Hello ${name}`, welcome</script>"#;
76 println!(
77 " for_js_template: {}",
78 for_js_template(template_input)
79 );
80 println!();
81
82 // quoted css string values, e.g., content: "..." or font-family: "..."
83 println!("--- css ---");
84 println!(" for_css_string: {}", for_css_string(input));
85
86 // css url() values — like for_css_string but parens pass through
87 println!(" for_css_url: {}", for_css_url(input));
88 println!();
89
90 // uri component (query params, path segments) — NOT for full urls
91 println!("--- uri ---");
92 println!(
93 " for_uri_component: {}",
94 for_uri_component(input)
95 );
96 println!();
97
98 // xml 1.0 aliases — identical to the html encoders
99 println!("--- xml 1.0 ---");
100 println!(" for_xml: {}", for_xml(input));
101 println!(" for_xml_content: {}", for_xml_content(input));
102 println!(
103 " for_xml_attribute: {}",
104 for_xml_attribute(input)
105 );
106
107 // xml-only contexts
108 println!(" for_xml_comment: {}", for_xml_comment(input));
109 println!(" for_cdata: {}", for_cdata(input));
110 println!();
111
112 // xml 1.1 — restricted chars get &#xHH; instead of space
113 println!("--- xml 1.1 ---");
114 let xml11_input = "a\x01b<c>";
115 println!(" for_xml11: {}", for_xml11(xml11_input));
116 println!(
117 " for_xml11_content: {}",
118 for_xml11_content(xml11_input)
119 );
120 println!(
121 " for_xml11_attribute: {}",
122 for_xml11_attribute(xml11_input)
123 );
124 println!();
125
126 // java string literal — octal escapes, surrogate pairs
127 println!("--- java ---");
128 println!(" for_java: {}", for_java(input));
129 println!();
130
131 // go literals — \xHH escapes, \a and \v named escapes
132 println!("--- go ---");
133 println!(" for_go_string: {}", for_go_string(input));
134 println!(" for_go_char: {}", for_go_char(input));
135 println!(
136 " for_go_byte_string: {}",
137 for_go_byte_string(input)
138 );
139 println!();
140
141 // rust literals — \xHH escapes, UTF-8 byte encoding for byte strings
142 println!("--- rust ---");
143 println!(" for_rust_string: {}", for_rust_string(input));
144 println!(" for_rust_char: {}", for_rust_char(input));
145 println!(
146 " for_rust_byte_string: {}",
147 for_rust_byte_string(input)
148 );
149 println!();
150
151 // json string value — \\uXXXX escapes for control chars and specials
152 println!("--- json ---");
153 println!(" for_json: {}", for_json(input));
154 println!();
155
156 // python literals — \\xHH escapes, raw strings can't end with odd backslashes
157 println!("--- python ---");
158 println!(
159 " for_python_string: {}",
160 for_python_string(input)
161 );
162 println!(
163 " for_python_bytes: {}",
164 for_python_bytes(input)
165 );
166 println!(
167 " for_python_raw_string: {}",
168 for_python_raw_string(input)
169 );
170 println!();
171
172 // sql string literals — single-quote doubling (standard) or backslash escaping (mysql)
173 println!("--- sql ---");
174 println!(" for_sql: {}", for_sql(input));
175 println!(
176 " for_sql_backslash: {}",
177 for_sql_backslash(input)
178 );
179
180 // -----------------------------------------------------------------------
181 // practical: one realistic input per sink, correct encoder for each
182 // -----------------------------------------------------------------------
183
184 let user_name = r#"Bob <img src=x onerror="alert(1)">"#;
185 let user_query = "hello world & goodbye";
186 let user_text = r#"hi from </script><script>alert(1)</script>"#;
187 let user_css_text = r#"hello "css" \ test"#;
188
189 println!("--- practical usage ---");
190
191 // html text node — for_html_content is the right encoder
192 println!(r#" <p>{}</p>"#, for_html_content(user_name));
193
194 // nested context: uri component inside an html attribute.
195 // encode from inside out: first percent-encode the query value,
196 // then html-attribute-encode the entire href.
197 let href = format!("/search?q={}", for_uri_component(user_query));
198 println!(r#" <a href="{}">search</a>"#, for_html_attribute(&href),);
199
200 // actual css string context: a quoted content value in a stylesheet
201 println!(
202 r#" <style>.msg::after {{ content: "{}"; }}</style>"#,
203 for_css_string(user_css_text),
204 );
205
206 // javascript string inside an event-handler attribute
207 println!(
208 r#" <button onclick="greet('{}');">hi</button>"#,
209 for_javascript_attribute(user_text),
210 );
211}