mirror of
https://github.com/actix/actix-web.git
synced 2024-11-25 11:01:14 +00:00
Quoter::requote
returns Vec<u8>
(#2613)
This commit is contained in:
parent
cd511affd5
commit
fd412a8223
4 changed files with 44 additions and 16 deletions
|
@ -1,6 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## 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
|
## 0.5.0-rc.2 - 2022-01-21
|
||||||
|
|
|
@ -52,7 +52,7 @@ macro_rules! parse_value {
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let decoded = FULL_QUOTER
|
let decoded = FULL_QUOTER
|
||||||
.with(|q| q.requote(self.value.as_bytes()))
|
.with(|q| q.requote_str_lossy(self.value))
|
||||||
.map(Cow::Owned)
|
.map(Cow::Owned)
|
||||||
.unwrap_or(Cow::Borrowed(self.value));
|
.unwrap_or(Cow::Borrowed(self.value));
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ impl<'de> Deserializer<'de> for Value<'de> {
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
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),
|
Some(s) => visitor.visit_string(s),
|
||||||
None => visitor.visit_borrowed_str(self.value),
|
None => visitor.visit_borrowed_str(self.value),
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ impl<'de> Deserializer<'de> for Value<'de> {
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
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()),
|
Some(s) => visitor.visit_byte_buf(s.into()),
|
||||||
None => visitor.visit_borrowed_bytes(self.value.as_bytes()),
|
None => visitor.visit_borrowed_bytes(self.value.as_bytes()),
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,13 @@ impl Quoter {
|
||||||
|
|
||||||
/// Re-quotes... ?
|
/// Re-quotes... ?
|
||||||
///
|
///
|
||||||
/// Returns `None` when no modification to the original string was required.
|
/// Returns `None` when no modification to the original byte string was required.
|
||||||
pub fn requote(&self, val: &[u8]) -> Option<String> {
|
///
|
||||||
|
/// 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 has_pct = 0;
|
||||||
let mut pct = [b'%', 0, 0];
|
let mut pct = [b'%', 0, 0];
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
|
@ -121,7 +126,12 @@ impl Quoter {
|
||||||
idx += 1;
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,14 +211,29 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn custom_quoter() {
|
fn custom_quoter() {
|
||||||
let q = Quoter::new(b"", b"+");
|
let q = Quoter::new(b"", b"+");
|
||||||
assert_eq!(q.requote(b"/a%25c").unwrap(), "/a%c");
|
assert_eq!(q.requote(b"/a%25c").unwrap(), b"/a%c");
|
||||||
assert_eq!(q.requote(b"/a%2Bc").unwrap(), "/a%2Bc");
|
assert_eq!(q.requote(b"/a%2Bc").unwrap(), b"/a%2Bc");
|
||||||
|
|
||||||
let q = Quoter::new(b"%+", b"/");
|
let q = Quoter::new(b"%+", b"/");
|
||||||
assert_eq!(q.requote(b"/a%25b%2Bc").unwrap(), "/a%b+c");
|
assert_eq!(q.requote(b"/a%25b%2Bc").unwrap(), b"/a%b+c");
|
||||||
assert_eq!(q.requote(b"/a%2fb").unwrap(), "/a%2fb");
|
assert_eq!(q.requote(b"/a%2fb").unwrap(), b"/a%2fb");
|
||||||
assert_eq!(q.requote(b"/a%2Fb").unwrap(), "/a%2Fb");
|
assert_eq!(q.requote(b"/a%2Fb").unwrap(), b"/a%2Fb");
|
||||||
assert_eq!(q.requote(b"/a%0Ab").unwrap(), "/a\nb");
|
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%2x%2X%%").unwrap(), b"/a%2x%2X");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -15,14 +15,14 @@ pub struct Url {
|
||||||
impl Url {
|
impl Url {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(uri: http::Uri) -> Url {
|
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 }
|
Url { uri, path }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_with_quoter(uri: http::Uri, quoter: &Quoter) -> Url {
|
pub fn new_with_quoter(uri: http::Uri, quoter: &Quoter) -> Url {
|
||||||
Url {
|
Url {
|
||||||
path: quoter.requote(uri.path().as_bytes()),
|
path: quoter.requote_str_lossy(uri.path()),
|
||||||
uri,
|
uri,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,13 +45,13 @@ impl Url {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn update(&mut self, uri: &http::Uri) {
|
pub fn update(&mut self, uri: &http::Uri) {
|
||||||
self.uri = uri.clone();
|
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]
|
#[inline]
|
||||||
pub fn update_with_quoter(&mut self, uri: &http::Uri, quoter: &Quoter) {
|
pub fn update_with_quoter(&mut self, uri: &http::Uri, quoter: &Quoter) {
|
||||||
self.uri = uri.clone();
|
self.uri = uri.clone();
|
||||||
self.path = quoter.requote(uri.path().as_bytes());
|
self.path = quoter.requote_str_lossy(uri.path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue