Decode in 'FromFormValue' as needed by 'FromStr'.

Fixes #1425.
This commit is contained in:
lewis 2020-09-07 16:31:45 +01:00 committed by Sergio Benitez
parent f976c15c25
commit 53d13a309b
2 changed files with 56 additions and 1 deletions

View File

@ -243,7 +243,24 @@ impl_with_fromstr!(
f32, f64, isize, i8, i16, i32, i64, i128, usize, u8, u16, u32, u64, u128,
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize,
NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6, SocketAddr
Ipv4Addr
);
macro_rules! impl_with_fromstr_encoded {
($($T:ident),+) => ($(
impl<'v> FromFormValue<'v> for $T {
type Error = &'v RawStr;
#[inline(always)]
fn from_form_value(v: &'v RawStr) -> Result<Self, Self::Error> {
$T::from_str(&v.url_decode().map_err(|_| v)?).map_err(|_| v)
}
}
)+)
}
impl_with_fromstr_encoded!(
IpAddr, Ipv6Addr, SocketAddrV4, SocketAddrV6, SocketAddr
);
impl<'v, T: FromFormValue<'v>> FromFormValue<'v> for Option<T> {

View File

@ -0,0 +1,38 @@
extern crate rocket;
use rocket::http::RawStr;
use rocket::request::FromFormValue;
use std::fmt::Debug;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
mod tests {
use super::*;
fn check_from_form_value_encoded<'a, T>(encoded_str: &'static str, expected: T)
where <T as FromFormValue<'a>>::Error: Debug,
T: FromFormValue<'a> + PartialEq + Debug,
{
let value = T::from_form_value(RawStr::from_str(encoded_str));
assert!(value.is_ok());
assert_eq!(value.unwrap(), expected);
}
#[test]
fn test_from_form_value_encoded() {
check_from_form_value_encoded(
"127.0.0.1%3A80",
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 80),
);
check_from_form_value_encoded(
"2001%3A0db8%3A85a3%3A0000%3A0000%3A8a2e%3A0370%3A7334",
Ipv6Addr::new(0x2001, 0x0db8, 0x85a3, 0, 0, 0x8a2e, 0x0370, 0x7334),
);
check_from_form_value_encoded(
"%5B2001%3Adb8%3A%3A1%5D%3A8080",
SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0),
);
}
}