Skip to content

Commit

Permalink
Merge pull request #281 from dralley/add-partial-escape
Browse files Browse the repository at this point in the history
Add a function for partially escaping element text
  • Loading branch information
tafia committed May 12, 2021
2 parents d00f9ca + 9f3d106 commit 356084e
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions src/escapei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,40 @@ impl std::error::Error for EscapeError {}
/// Escapes a `&[u8]` and replaces all xml special characters (<, >, &, ', ") with their
/// corresponding xml escaped value.
pub fn escape(raw: &[u8]) -> Cow<[u8]> {
#[inline]
fn to_escape(b: u8) -> bool {
match b {
b'<' | b'>' | b'\'' | b'&' | b'"' => true,
_ => false,
}
}

_escape(raw, to_escape)
}

/// Should only be used for escaping text content. In xml text content, it is allowed
/// (though not recommended) to leave the quote special characters " and ' unescaped.
/// This function escapes a `&[u8]` and replaces xml special characters (<, >, &) with
/// their corresponding xml escaped value, but does not escape quote characters.
pub fn partial_escape(raw: &[u8]) -> Cow<[u8]> {
#[inline]
fn to_escape(b: u8) -> bool {
match b {
b'<' | b'>' | b'&' => true,
_ => false,
}
}

_escape(raw, to_escape)
}

/// Escapes a `&[u8]` and replaces a subset of xml special characters (<, >, &, ', ") with their
/// corresponding xml escaped value.
fn _escape<F: Fn(u8) -> bool>(raw: &[u8], escape_chars: F) -> Cow<[u8]> {
let mut escaped = None;
let mut bytes = raw.iter();
let mut pos = 0;
while let Some(i) = bytes.position(|&b| to_escape(b)) {
while let Some(i) = bytes.position(|&b| escape_chars(b)) {
if escaped.is_none() {
escaped = Some(Vec::with_capacity(raw.len()));
}
Expand Down Expand Up @@ -120,7 +143,7 @@ pub fn unescape_with<'a>(
}

/// Unescape a `&[u8]` and replaces all xml escaped characters ('&...;') into their corresponding
/// value, using an optional dictionnary of custom entities.
/// value, using an optional dictionary of custom entities.
///
/// # Pre-condition
///
Expand Down Expand Up @@ -1738,3 +1761,15 @@ fn test_escape() {
"prefix_&quot;a&quot;b&amp;&lt;&gt;c".as_bytes()
);
}

#[test]
fn test_partial_escape() {
assert_eq!(&*partial_escape(b"test"), b"test");
assert_eq!(&*partial_escape(b"<test>"), b"&lt;test&gt;");
assert_eq!(&*partial_escape(b"\"a\"bc"), b"\"a\"bc");
assert_eq!(&*partial_escape(b"\"a\"b&c"), b"\"a\"b&amp;c");
assert_eq!(
&*partial_escape(b"prefix_\"a\"b&<>c"),
"prefix_\"a\"b&amp;&lt;&gt;c".as_bytes()
);
}

0 comments on commit 356084e

Please sign in to comment.