Disallow deserialize empty GraphQLBatchRequest (#639) (#644)

* Disallow deserialize empty GraphQLBatchRequest (#639)

* Add test for empty batch request
This commit is contained in:
Kai Ren 2020-04-30 19:16:15 +03:00 committed by GitHub
parent 845331033e
commit 52aea4d68d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,6 +4,7 @@ pub mod graphiql;
pub mod playground; pub mod playground;
use serde::{ use serde::{
de,
ser::{self, SerializeMap}, ser::{self, SerializeMap},
Deserialize, Serialize, Deserialize, Serialize,
}; };
@ -216,7 +217,7 @@ where
} }
} }
/// Simple wrapper around GraphQLRequest to allow the handling of Batch requests /// Simple wrapper around GraphQLRequest to allow the handling of Batch requests.
#[derive(Debug, Deserialize, PartialEq)] #[derive(Debug, Deserialize, PartialEq)]
#[serde(untagged)] #[serde(untagged)]
#[serde(bound = "InputValue<S>: Deserialize<'de>")] #[serde(bound = "InputValue<S>: Deserialize<'de>")]
@ -226,10 +227,29 @@ where
{ {
/// A single operation request. /// A single operation request.
Single(GraphQLRequest<S>), Single(GraphQLRequest<S>),
/// A batch operation request. /// A batch operation request.
///
/// Empty batch is considered as invalid value, so cannot be deserialized.
#[serde(deserialize_with = "deserialize_non_empty_vec")]
Batch(Vec<GraphQLRequest<S>>), Batch(Vec<GraphQLRequest<S>>),
} }
fn deserialize_non_empty_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: de::Deserializer<'de>,
T: Deserialize<'de>,
{
use de::Error as _;
let v = Vec::<T>::deserialize(deserializer)?;
if v.is_empty() {
Err(D::Error::invalid_length(0, &"a positive integer"))
} else {
Ok(v)
}
}
impl<S> GraphQLBatchRequest<S> impl<S> GraphQLBatchRequest<S>
where where
S: ScalarValue, S: ScalarValue,
@ -373,6 +393,9 @@ pub mod tests {
println!(" - test_batched_post"); println!(" - test_batched_post");
test_batched_post(integration); test_batched_post(integration);
println!(" - test_empty_batched_post");
test_empty_batched_post(integration);
println!(" - test_invalid_json"); println!(" - test_invalid_json");
test_invalid_json(integration); test_invalid_json(integration);
@ -499,6 +522,11 @@ pub mod tests {
); );
} }
fn test_empty_batched_post<T: HTTPIntegration>(integration: &T) {
let response = integration.post("/", "[]");
assert_eq!(response.status_code, 400);
}
fn test_invalid_json<T: HTTPIntegration>(integration: &T) { fn test_invalid_json<T: HTTPIntegration>(integration: &T) {
let response = integration.get("/?query=blah"); let response = integration.get("/?query=blah");
assert_eq!(response.status_code, 400); assert_eq!(response.status_code, 400);