Skip to content

Commit

Permalink
Fix tafia#517: Fix swapped codes for \r and \n characters when es…
Browse files Browse the repository at this point in the history
…caping them

Co-authored-by: Daniel Alley <dalley@redhat.com>
  • Loading branch information
Mingun and dralley committed Dec 2, 2022
1 parent 78a1cf5 commit ebaffb3
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 53 deletions.
2 changes: 2 additions & 0 deletions Changelog.md
Expand Up @@ -28,6 +28,7 @@
```
- [#514]: Fix wrong reporting `Error::EndEventMismatch` after disabling and enabling
`.check_end_names`
- [#517]: Fix swapped codes for `\r` and `\n` characters when escaping them

### Misc Changes

Expand Down Expand Up @@ -56,6 +57,7 @@
[#490]: https://github.com/tafia/quick-xml/pull/490
[#500]: https://github.com/tafia/quick-xml/issues/500
[#514]: https://github.com/tafia/quick-xml/issues/514
[#517]: https://github.com/tafia/quick-xml/issues/517
[XML name]: https://www.w3.org/TR/xml11/#NT-Name
[documentation]: https://docs.rs/quick-xml/0.27.0/quick_xml/de/index.html#difference-between-text-and-value-special-names

Expand Down
4 changes: 2 additions & 2 deletions src/escapei.rs
Expand Up @@ -117,8 +117,8 @@ pub(crate) fn _escape<F: Fn(u8) -> bool>(raw: &str, escape_chars: F) -> Cow<str>
// in elements of xs:lists, because those characters works as
// delimiters of list elements
b'\t' => escaped.extend_from_slice(b"&#9;"),
b'\r' => escaped.extend_from_slice(b"&#10;"),
b'\n' => escaped.extend_from_slice(b"&#13;"),
b'\n' => escaped.extend_from_slice(b"&#10;"),
b'\r' => escaped.extend_from_slice(b"&#13;"),
b' ' => escaped.extend_from_slice(b"&#32;"),
_ => unreachable!(
"Only '<', '>','\', '&', '\"', '\\t', '\\r', '\\n', and ' ' are escaped"
Expand Down
44 changes: 22 additions & 22 deletions src/se/element.rs
Expand Up @@ -627,9 +627,9 @@ mod tests {
<root>2</root>\
<root>3</root>");
serialize_as!(seq_empty: Vec::<usize>::new() => "");
serialize_as!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
serialize_as!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "<root>&lt;&quot;&amp;&apos;&gt;</root>\
<root>with\t\r\n spaces</root>\
<root>with\t\n\r spaces</root>\
<root>3</root>");
serialize_as!(tuple_struct: Tuple("first", 42)
=> "<root>first</root>\
Expand Down Expand Up @@ -747,7 +747,7 @@ mod tests {
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new());
text!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; \
with&#9;&#10;&#13;&#32;spaces \
3");
Expand Down Expand Up @@ -874,7 +874,7 @@ mod tests {
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new() => "");
text!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; \
with&#9;&#10;&#13;&#32;spaces \
3");
Expand Down Expand Up @@ -1001,7 +1001,7 @@ mod tests {
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new() => "");
text!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; \
with&#9;&#10;&#13;&#32;spaces \
3");
Expand Down Expand Up @@ -1123,9 +1123,9 @@ mod tests {
// Note that sequences of primitives serialized without delimiters!
value!(seq: vec![1, 2, 3] => "123");
value!(seq_empty: Vec::<usize>::new());
value!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
value!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt;\
with\t\r\n spaces\
with\t\n\r spaces\
3");
value!(tuple_struct: Tuple("first", 42) => "first42");
value!(enum_tuple: Enum::Tuple("first", 42)
Expand Down Expand Up @@ -1237,9 +1237,9 @@ mod tests {
// Note that sequences of primitives serialized without delimiters!
value!(seq: vec![1, 2, 3] => "123");
value!(seq_empty: Vec::<usize>::new() => "");
value!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
value!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt;\
with\t\r\n spaces\
with\t\n\r spaces\
3");
value!(tuple_struct: Tuple("first", 42) => "first42");
value!(enum_tuple: Enum::Tuple("first", 42)
Expand Down Expand Up @@ -1359,9 +1359,9 @@ mod tests {
// Note that sequences of primitives serialized without delimiters!
value!(seq: vec![1, 2, 3] => "123");
value!(seq_empty: Vec::<usize>::new() => "");
value!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
value!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt;\
with\t\r\n spaces\
with\t\n\r spaces\
3");
value!(tuple_struct: Tuple("first", 42) => "first42");
value!(enum_tuple: Enum::Tuple("first", 42)
Expand Down Expand Up @@ -1588,9 +1588,9 @@ mod tests {
<root>2</root>\n\
<root>3</root>");
serialize_as!(seq_empty: Vec::<usize>::new() => "");
serialize_as!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
serialize_as!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "<root>&lt;&quot;&amp;&apos;&gt;</root>\n\
<root>with\t\r\n spaces</root>\n\
<root>with\t\n\r spaces</root>\n\
<root>3</root>");
serialize_as!(tuple_struct: Tuple("first", 42)
=> "<root>first</root>\n\
Expand Down Expand Up @@ -1708,7 +1708,7 @@ mod tests {
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new());
text!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; \
with&#9;&#10;&#13;&#32;spaces \
3");
Expand Down Expand Up @@ -1847,7 +1847,7 @@ mod tests {
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new());
text!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; \
with&#9;&#10;&#13;&#32;spaces \
3");
Expand Down Expand Up @@ -1986,7 +1986,7 @@ mod tests {
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new());
text!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; \
with&#9;&#10;&#13;&#32;spaces \
3");
Expand Down Expand Up @@ -2107,9 +2107,9 @@ mod tests {

value!(seq: vec![1, 2, 3] => "1\n 2\n 3");
value!(seq_empty: Vec::<usize>::new());
value!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
value!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt;\n \
with\t\r\n spaces\n \
with\t\n\r spaces\n \
3");
value!(tuple_struct: Tuple("first", 42) => "first\n 42");
value!(enum_tuple: Enum::Tuple("first", 42)
Expand Down Expand Up @@ -2233,9 +2233,9 @@ mod tests {
// Note that sequences of primitives serialized without delimiters!
value!(seq: vec![1, 2, 3] => "1\n 2\n 3");
value!(seq_empty: Vec::<usize>::new());
value!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
value!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt;\n \
with\t\r\n spaces\n \
with\t\n\r spaces\n \
3");
value!(tuple_struct: Tuple("first", 42) => "first\n 42");
value!(enum_tuple: Enum::Tuple("first", 42)
Expand Down Expand Up @@ -2367,9 +2367,9 @@ mod tests {
// Note that sequences of primitives serialized without delimiters!
value!(seq: vec![1, 2, 3] => "1\n 2\n 3");
value!(seq_empty: Vec::<usize>::new());
value!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
value!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt;\n \
with\t\r\n spaces\n \
with\t\n\r spaces\n \
3");
value!(tuple_struct: Tuple("first", 42) => "first\n 42");
value!(enum_tuple: Enum::Tuple("first", 42)
Expand Down
58 changes: 29 additions & 29 deletions src/se/simple_type.rs
Expand Up @@ -587,7 +587,7 @@ mod tests {
#[test]
fn text() {
assert_eq!(
escape_item("text<\"'&> \t\r\ntext", QuoteTarget::Text, QuoteLevel::Full),
escape_item("text<\"'&> \t\n\rtext", QuoteTarget::Text, QuoteLevel::Full),
"text&lt;&quot;&apos;&amp;&gt;&#32;&#9;&#10;&#13;text"
);
}
Expand All @@ -596,7 +596,7 @@ mod tests {
fn double_quote_attr() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::DoubleQAttr,
QuoteLevel::Full
),
Expand All @@ -608,7 +608,7 @@ mod tests {
fn single_quote_attr() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::SingleQAttr,
QuoteLevel::Full
),
Expand All @@ -625,7 +625,7 @@ mod tests {
fn text() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::Text,
QuoteLevel::Partial
),
Expand All @@ -637,7 +637,7 @@ mod tests {
fn double_quote_attr() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::DoubleQAttr,
QuoteLevel::Partial
),
Expand All @@ -649,7 +649,7 @@ mod tests {
fn single_quote_attr() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::SingleQAttr,
QuoteLevel::Partial
),
Expand All @@ -666,7 +666,7 @@ mod tests {
fn text() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::Text,
QuoteLevel::Minimal
),
Expand All @@ -678,7 +678,7 @@ mod tests {
fn double_quote_attr() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::DoubleQAttr,
QuoteLevel::Minimal
),
Expand All @@ -690,7 +690,7 @@ mod tests {
fn single_quote_attr() {
assert_eq!(
escape_item(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::SingleQAttr,
QuoteLevel::Minimal
),
Expand All @@ -710,32 +710,32 @@ mod tests {
#[test]
fn text() {
assert_eq!(
escape_list("text<\"'&> \t\r\ntext", QuoteTarget::Text, QuoteLevel::Full),
"text&lt;&quot;&apos;&amp;&gt; \t\r\ntext"
escape_list("text<\"'&> \t\n\rtext", QuoteTarget::Text, QuoteLevel::Full),
"text&lt;&quot;&apos;&amp;&gt; \t\n\rtext"
);
}

#[test]
fn double_quote_attr() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::DoubleQAttr,
QuoteLevel::Full
),
"text&lt;&quot;&apos;&amp;&gt; \t\r\ntext"
"text&lt;&quot;&apos;&amp;&gt; \t\n\rtext"
);
}

#[test]
fn single_quote_attr() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::SingleQAttr,
QuoteLevel::Full
),
"text&lt;&quot;&apos;&amp;&gt; \t\r\ntext"
"text&lt;&quot;&apos;&amp;&gt; \t\n\rtext"
);
}
}
Expand All @@ -748,35 +748,35 @@ mod tests {
fn text() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::Text,
QuoteLevel::Partial
),
"text&lt;\"'&amp;&gt; \t\r\ntext"
"text&lt;\"'&amp;&gt; \t\n\rtext"
);
}

#[test]
fn double_quote_attr() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::DoubleQAttr,
QuoteLevel::Partial
),
"text&lt;&quot;'&amp;&gt; \t\r\ntext"
"text&lt;&quot;'&amp;&gt; \t\n\rtext"
);
}

#[test]
fn single_quote_attr() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::SingleQAttr,
QuoteLevel::Partial
),
"text&lt;\"&apos;&amp;&gt; \t\r\ntext"
"text&lt;\"&apos;&amp;&gt; \t\n\rtext"
);
}
}
Expand All @@ -789,35 +789,35 @@ mod tests {
fn text() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::Text,
QuoteLevel::Minimal
),
"text&lt;\"'&amp;> \t\r\ntext"
"text&lt;\"'&amp;> \t\n\rtext"
);
}

#[test]
fn double_quote_attr() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::DoubleQAttr,
QuoteLevel::Minimal
),
"text&lt;&quot;'&amp;> \t\r\ntext"
"text&lt;&quot;'&amp;> \t\n\rtext"
);
}

#[test]
fn single_quote_attr() {
assert_eq!(
escape_list(
"text<\"'&> \t\r\ntext",
"text<\"'&> \t\n\rtext",
QuoteTarget::SingleQAttr,
QuoteLevel::Minimal
),
"text&lt;\"&apos;&amp;> \t\r\ntext"
"text&lt;\"&apos;&amp;> \t\n\rtext"
);
}
}
Expand Down Expand Up @@ -925,7 +925,7 @@ mod tests {

err!(seq: vec![1, 2, 3]
=> Unsupported("sequence cannot be serialized as an `xs:list` item"));
err!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
err!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> Unsupported("tuple cannot be serialized as an `xs:list` item"));
err!(tuple_struct: Tuple("first", 42)
=> Unsupported("tuple struct `Tuple` cannot be serialized as an `xs:list` item"));
Expand Down Expand Up @@ -1043,7 +1043,7 @@ mod tests {
serialize_as!(seq_empty: Vec::<usize>::new() => "");
serialize_as!(seq_with_1_empty_str: vec![""] => "");
serialize_as!(seq_with_2_empty_strs: vec!["", ""] => " ");
serialize_as!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
serialize_as!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "&lt;&quot;&amp;&apos;&gt; with&#9;&#10;&#13;&#32;spaces 3");
serialize_as!(tuple_struct: Tuple("first", 42) => "first 42");
err!(enum_tuple: Enum::Tuple("first", 42)
Expand Down

0 comments on commit ebaffb3

Please sign in to comment.