Skip to content

Commit

Permalink
Quoter::requote returns Vec<u8> (actix#2613)
Browse files Browse the repository at this point in the history
  • Loading branch information
aliemjay authored Jan 31, 2022
1 parent cd511af commit fd412a8
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 16 deletions.
3 changes: 3 additions & 0 deletions actix-router/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changes

## Unreleased - 2021-xx-xx
- `Quoter::requote` now returns `Option<Vec<u8>>`. [#2613]

[#2613]: https://github.com/actix/actix-web/pull/2613


## 0.5.0-rc.2 - 2022-01-21
Expand Down
6 changes: 3 additions & 3 deletions actix-router/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ macro_rules! parse_value {
V: Visitor<'de>,
{
let decoded = FULL_QUOTER
.with(|q| q.requote(self.value.as_bytes()))
.with(|q| q.requote_str_lossy(self.value))
.map(Cow::Owned)
.unwrap_or(Cow::Borrowed(self.value));

Expand Down Expand Up @@ -332,7 +332,7 @@ impl<'de> Deserializer<'de> for Value<'de> {
where
V: Visitor<'de>,
{
match FULL_QUOTER.with(|q| q.requote(self.value.as_bytes())) {
match FULL_QUOTER.with(|q| q.requote_str_lossy(self.value)) {
Some(s) => visitor.visit_string(s),
None => visitor.visit_borrowed_str(self.value),
}
Expand All @@ -342,7 +342,7 @@ impl<'de> Deserializer<'de> for Value<'de> {
where
V: Visitor<'de>,
{
match FULL_QUOTER.with(|q| q.requote(self.value.as_bytes())) {
match FULL_QUOTER.with(|q| q.requote_str_lossy(self.value)) {
Some(s) => visitor.visit_byte_buf(s.into()),
None => visitor.visit_borrowed_bytes(self.value.as_bytes()),
}
Expand Down
43 changes: 34 additions & 9 deletions actix-router/src/quoter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,13 @@ impl Quoter {

/// Re-quotes... ?
///
/// Returns `None` when no modification to the original string was required.
pub fn requote(&self, val: &[u8]) -> Option<String> {
/// Returns `None` when no modification to the original byte string was required.
///
/// Non-ASCII bytes are accepted as valid input.
///
/// Behavior for invalid/incomplete percent-encoding sequences is unspecified and may include removing
/// the invalid sequence from the output or passing it as it is.
pub fn requote(&self, val: &[u8]) -> Option<Vec<u8>> {
let mut has_pct = 0;
let mut pct = [b'%', 0, 0];
let mut idx = 0;
Expand Down Expand Up @@ -121,7 +126,12 @@ impl Quoter {
idx += 1;
}

cloned.map(|data| String::from_utf8_lossy(&data).into_owned())
cloned
}

pub(crate) fn requote_str_lossy(&self, val: &str) -> Option<String> {
self.requote(val.as_bytes())
.map(|data| String::from_utf8_lossy(&data).into_owned())
}
}

Expand Down Expand Up @@ -201,14 +211,29 @@ mod tests {
#[test]
fn custom_quoter() {
let q = Quoter::new(b"", b"+");
assert_eq!(q.requote(b"/a%25c").unwrap(), "/a%c");
assert_eq!(q.requote(b"/a%2Bc").unwrap(), "/a%2Bc");
assert_eq!(q.requote(b"/a%25c").unwrap(), b"/a%c");
assert_eq!(q.requote(b"/a%2Bc").unwrap(), b"/a%2Bc");

let q = Quoter::new(b"%+", b"/");
assert_eq!(q.requote(b"/a%25b%2Bc").unwrap(), b"/a%b+c");
assert_eq!(q.requote(b"/a%2fb").unwrap(), b"/a%2fb");
assert_eq!(q.requote(b"/a%2Fb").unwrap(), b"/a%2Fb");
assert_eq!(q.requote(b"/a%0Ab").unwrap(), b"/a\nb");
assert_eq!(q.requote(b"/a%FE\xffb").unwrap(), b"/a\xfe\xffb");
assert_eq!(q.requote(b"/a\xfe\xffb"), None);
}

#[test]
fn non_ascii() {
let q = Quoter::new(b"%+", b"/");
assert_eq!(q.requote(b"/a%FE\xffb").unwrap(), b"/a\xfe\xffb");
assert_eq!(q.requote(b"/a\xfe\xffb"), None);
}

#[test]
fn invalid_sequences() {
let q = Quoter::new(b"%+", b"/");
assert_eq!(q.requote(b"/a%25b%2Bc").unwrap(), "/a%b+c");
assert_eq!(q.requote(b"/a%2fb").unwrap(), "/a%2fb");
assert_eq!(q.requote(b"/a%2Fb").unwrap(), "/a%2Fb");
assert_eq!(q.requote(b"/a%0Ab").unwrap(), "/a\nb");
assert_eq!(q.requote(b"/a%2x%2X%%").unwrap(), b"/a%2x%2X");
}

#[test]
Expand Down
8 changes: 4 additions & 4 deletions actix-router/src/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ pub struct Url {
impl Url {
#[inline]
pub fn new(uri: http::Uri) -> Url {
let path = DEFAULT_QUOTER.with(|q| q.requote(uri.path().as_bytes()));
let path = DEFAULT_QUOTER.with(|q| q.requote_str_lossy(uri.path()));
Url { uri, path }
}

#[inline]
pub fn new_with_quoter(uri: http::Uri, quoter: &Quoter) -> Url {
Url {
path: quoter.requote(uri.path().as_bytes()),
path: quoter.requote_str_lossy(uri.path()),
uri,
}
}
Expand All @@ -45,13 +45,13 @@ impl Url {
#[inline]
pub fn update(&mut self, uri: &http::Uri) {
self.uri = uri.clone();
self.path = DEFAULT_QUOTER.with(|q| q.requote(uri.path().as_bytes()));
self.path = DEFAULT_QUOTER.with(|q| q.requote_str_lossy(uri.path()));
}

#[inline]
pub fn update_with_quoter(&mut self, uri: &http::Uri, quoter: &Quoter) {
self.uri = uri.clone();
self.path = quoter.requote(uri.path().as_bytes());
self.path = quoter.requote_str_lossy(uri.path());
}
}

Expand Down

0 comments on commit fd412a8

Please sign in to comment.