Skip to main content

for_html_attribute

Function for_html_attribute 

Source
pub fn for_html_attribute(input: &str) -> String
Expand 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

inputoutput
&&
<&lt;
"&#34;
'&#39;

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&#39;s a &#34;test&#34;"
);
// > 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}