Skip to content

Commit

Permalink
Disallow deserialize empty GraphQLBatchRequest (#639) (#644)
Browse files Browse the repository at this point in the history
* Disallow deserialize empty GraphQLBatchRequest (#639)

* Add test for empty batch request
  • Loading branch information
tyranron authored Apr 30, 2020
1 parent 8453310 commit 52aea4d
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion juniper/src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod graphiql;
pub mod playground;

use serde::{
de,
ser::{self, SerializeMap},
Deserialize, Serialize,
};
Expand Down Expand Up @@ -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)]
#[serde(untagged)]
#[serde(bound = "InputValue<S>: Deserialize<'de>")]
Expand All @@ -226,10 +227,29 @@ where
{
/// A single operation request.
Single(GraphQLRequest<S>),

/// 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>>),
}

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>
where
S: ScalarValue,
Expand Down Expand Up @@ -373,6 +393,9 @@ pub mod tests {
println!(" - test_batched_post");
test_batched_post(integration);

println!(" - test_empty_batched_post");
test_empty_batched_post(integration);

println!(" - test_invalid_json");
test_invalid_json(integration);

Expand Down Expand Up @@ -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) {
let response = integration.get("/?query=blah");
assert_eq!(response.status_code, 400);
Expand Down

0 comments on commit 52aea4d

Please sign in to comment.