1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-01-18 20:01:48 +01:00

router: handle newline char '\n' in url (#360)

This commit is contained in:
Ali MJ Al-Nasrawy 2021-06-06 05:38:58 +03:00 committed by GitHub
parent 3aa037d07d
commit 23b1f63345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 2 deletions

View File

@ -4,10 +4,12 @@
* `Path::add` and `add_static` takes `impl Into<Cow<'static, str>>` [#345] * `Path::add` and `add_static` takes `impl Into<Cow<'static, str>>` [#345]
* When matching URL parameters, `%25` is kept in the percent-encoded form - no longer decoded to `%`. [#357] * When matching URL parameters, `%25` is kept in the percent-encoded form - no longer decoded to `%`. [#357]
* Fixed a bug where the `Path` extractor returns unsafe malformed string due to malformed URL. [#359] * Fixed a bug where the `Path` extractor returns unsafe malformed string due to malformed URL. [#359]
* Path tail patterns now match `'\n'` in request URL. [#360]
[#345]: https://github.com/actix/actix-net/pull/345 [#345]: https://github.com/actix/actix-net/pull/345
[#357]: https://github.com/actix/actix-net/pull/357 [#357]: https://github.com/actix/actix-net/pull/357
[#359]: https://github.com/actix/actix-net/pull/359 [#359]: https://github.com/actix/actix-net/pull/359
[#360]: https://github.com/actix/actix-net/pull/360
## 0.2.7 - 2021-02-06 ## 0.2.7 - 2021-02-06

View File

@ -10,6 +10,11 @@ use crate::{IntoPattern, Resource, ResourcePath};
const MAX_DYNAMIC_SEGMENTS: usize = 16; const MAX_DYNAMIC_SEGMENTS: usize = 16;
/// Regex flags to allow '.' in regex to match '\n'
///
/// See the docs under: https://docs.rs/regex/1.5.4/regex/#grouping-and-flags
const REGEX_FLAGS: &str = "(?s-m)";
/// ResourceDef describes an entry in resources table /// ResourceDef describes an entry in resources table
/// ///
/// Resource definition can contain only 16 dynamic segments /// Resource definition can contain only 16 dynamic segments
@ -571,7 +576,7 @@ impl ResourceDef {
) -> (String, Vec<PatternElement>, bool, usize) { ) -> (String, Vec<PatternElement>, bool, usize) {
if pattern.find('{').is_none() { if pattern.find('{').is_none() {
return if let Some(path) = pattern.strip_suffix('*') { return if let Some(path) = pattern.strip_suffix('*') {
let re = String::from("^") + path + "(.*)"; let re = format!("{}^{}(.*)", REGEX_FLAGS, path);
(re, vec![PatternElement::Str(String::from(path))], true, 0) (re, vec![PatternElement::Str(String::from(path))], true, 0)
} else { } else {
( (
@ -584,7 +589,7 @@ impl ResourceDef {
} }
let mut elements = Vec::new(); let mut elements = Vec::new();
let mut re = String::from("^"); let mut re = format!("{}^", REGEX_FLAGS);
let mut dyn_elements = 0; let mut dyn_elements = 0;
while let Some(idx) = pattern.find('{') { while let Some(idx) = pattern.find('{') {
@ -817,6 +822,32 @@ mod tests {
assert!(re.is_match("/user/2345/sdg")); assert!(re.is_match("/user/2345/sdg"));
} }
#[test]
fn test_newline() {
let re = ResourceDef::new("/user/a\nb");
assert!(re.is_match("/user/a\nb"));
assert!(!re.is_match("/user/a\nb/profile"));
let re = ResourceDef::new("/a{x}b/test/a{y}b");
let mut path = Path::new("/a\nb/test/a\nb");
assert!(re.match_path(&mut path));
assert_eq!(path.get("x").unwrap(), "\n");
assert_eq!(path.get("y").unwrap(), "\n");
let re = ResourceDef::new("/user/*");
assert!(re.is_match("/user/a\nb/"));
let re = ResourceDef::new("/user/{id}*");
let mut path = Path::new("/user/a\nb/a\nb");
assert!(re.match_path(&mut path));
assert_eq!(path.get("id").unwrap(), "a\nb/a\nb");
let re = ResourceDef::new("/user/{id:.*}");
let mut path = Path::new("/user/a\nb/a\nb");
assert!(re.match_path(&mut path));
assert_eq!(path.get("id").unwrap(), "a\nb/a\nb");
}
#[cfg(feature = "http")] #[cfg(feature = "http")]
#[test] #[test]
fn test_parse_urlencoded_param() { fn test_parse_urlencoded_param() {