Skip to main content

for_xml11

Function for_xml11 

Source
pub fn for_xml11(input: &str) -> String
Expand description

encodes input for safe embedding in XML 1.1 text content and quoted attributes.

like for_xml but encodes restricted characters as &#xHH; character references instead of replacing them with space. NUL (U+0000) and unicode non-characters are still replaced with space (they are invalid in XML 1.1).

NEL (U+0085) is not restricted in XML 1.1 and passes through unchanged.

§examples

use contextual_encoder::for_xml11;

assert_eq!(for_xml11("<b>"), "&lt;b&gt;");
// control chars get character references instead of space
assert_eq!(for_xml11("a\x01b"), "a&#x1;b");
// NEL passes through in XML 1.1
assert_eq!(for_xml11("a\u{0085}b"), "a\u{0085}b");
Examples found in repository?
examples/contexts.rs (line 120)
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 / json 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 — like for_css_string but parens pass through
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!("  for_rust_char:                {}", for_rust_char(input));
135    println!(
136        "  for_rust_byte_string:         {}",
137        for_rust_byte_string(input)
138    );
139    println!();
140
141    // json string value — \\uXXXX escapes for control chars and specials
142    println!("--- json ---");
143    println!("  for_json:                     {}", for_json(input));
144    println!();
145
146    // sql string literals — single-quote doubling (standard) or backslash escaping (mysql)
147    println!("--- sql ---");
148    println!("  for_sql:                      {}", for_sql(input));
149    println!(
150        "  for_sql_backslash:            {}",
151        for_sql_backslash(input)
152    );
153
154    // -----------------------------------------------------------------------
155    // practical: one realistic input per sink, correct encoder for each
156    // -----------------------------------------------------------------------
157
158    let user_name = r#"Bob <img src=x onerror="alert(1)">"#;
159    let user_query = "hello world & goodbye";
160    let user_text = r#"hi from </script><script>alert(1)</script>"#;
161    let user_css_text = r#"hello "css" \ test"#;
162
163    println!("--- practical usage ---");
164
165    // html text node — for_html_content is the right encoder
166    println!(r#"  <p>{}</p>"#, for_html_content(user_name));
167
168    // nested context: uri component inside an html attribute.
169    // encode from inside out: first percent-encode the query value,
170    // then html-attribute-encode the entire href.
171    let href = format!("/search?q={}", for_uri_component(user_query));
172    println!(r#"  <a href="{}">search</a>"#, for_html_attribute(&href),);
173
174    // actual css string context: a quoted content value in a stylesheet
175    println!(
176        r#"  <style>.msg::after {{ content: "{}"; }}</style>"#,
177        for_css_string(user_css_text),
178    );
179
180    // javascript string inside an event-handler attribute
181    println!(
182        r#"  <button onclick="greet('{}');">hi</button>"#,
183        for_javascript_attribute(user_text),
184    );
185}