mirror of
https://github.com/tokio-rs/axum.git
synced 2024-12-28 07:20:12 +01:00
Stricter path deserialization for tuples and tuple structs (#2931)
This commit is contained in:
parent
068c9a3e96
commit
4179d11797
3 changed files with 47 additions and 16 deletions
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
# Unreleased
|
||||
|
||||
- **breaking:** The tuple and tuple_struct `Path` extractor deserializers now check that the number of parameters matches the tuple length exactly ([#2931])
|
||||
|
||||
[#2931]: https://github.com/tokio-rs/axum/pull/2931
|
||||
|
||||
# 0.7.6
|
||||
|
||||
- **change:** Avoid cloning `Arc` during deserialization of `Path`
|
||||
|
|
|
@ -140,7 +140,7 @@ impl<'de> Deserializer<'de> for PathDeserializer<'de> {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
if self.url_params.len() < len {
|
||||
if self.url_params.len() != len {
|
||||
return Err(PathDeserializationError::wrong_number_of_parameters()
|
||||
.got(self.url_params.len())
|
||||
.expected(len));
|
||||
|
@ -160,7 +160,7 @@ impl<'de> Deserializer<'de> for PathDeserializer<'de> {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
if self.url_params.len() < len {
|
||||
if self.url_params.len() != len {
|
||||
return Err(PathDeserializationError::wrong_number_of_parameters()
|
||||
.got(self.url_params.len())
|
||||
.expected(len));
|
||||
|
@ -773,20 +773,6 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_tuple_ignoring_additional_fields() {
|
||||
let url_params = create_url_params(vec![
|
||||
("a", "abc"),
|
||||
("b", "true"),
|
||||
("c", "1"),
|
||||
("d", "false"),
|
||||
]);
|
||||
assert_eq!(
|
||||
<(&str, bool, u32)>::deserialize(PathDeserializer::new(&url_params)).unwrap(),
|
||||
("abc", true, 1)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_map() {
|
||||
let url_params = create_url_params(vec![("a", "1"), ("b", "true"), ("c", "abc")]);
|
||||
|
@ -813,6 +799,18 @@ mod tests {
|
|||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_tuple_too_many_fields() {
|
||||
test_parse_error!(
|
||||
vec![("a", "abc"), ("b", "true"), ("c", "1"), ("d", "false"),],
|
||||
(&str, bool, u32),
|
||||
ErrorKind::WrongNumberOfParameters {
|
||||
got: 4,
|
||||
expected: 3,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrong_number_of_parameters_error() {
|
||||
test_parse_error!(
|
||||
|
|
|
@ -747,6 +747,33 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[crate::test]
|
||||
async fn tuple_param_matches_exactly() {
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
struct Tuple(String, String);
|
||||
|
||||
let app = Router::new()
|
||||
.route("/foo/:a/:b/:c", get(|_: Path<(String, String)>| async {}))
|
||||
.route("/bar/:a/:b/:c", get(|_: Path<Tuple>| async {}));
|
||||
|
||||
let client = TestClient::new(app);
|
||||
|
||||
let res = client.get("/foo/a/b/c").await;
|
||||
assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
assert_eq!(
|
||||
res.text().await,
|
||||
"Wrong number of path arguments for `Path`. Expected 2 but got 3",
|
||||
);
|
||||
|
||||
let res = client.get("/bar/a/b/c").await;
|
||||
assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
assert_eq!(
|
||||
res.text().await,
|
||||
"Wrong number of path arguments for `Path`. Expected 2 but got 3",
|
||||
);
|
||||
}
|
||||
|
||||
#[crate::test]
|
||||
async fn deserialize_into_vec_of_tuples() {
|
||||
let app = Router::new().route(
|
||||
|
|
Loading…
Reference in a new issue