Skip to content

Commit 472aad5

Browse files
authored
Merge pull request #361 from noverby/302-fix-overflow
Fix overflow for recursive types
2 parents da80b9a + 7c05710 commit 472aad5

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

graphql_client_codegen/src/schema.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod tests;
66

77
use crate::query::UsedTypes;
88
use crate::type_qualifiers::GraphqlTypeQualifier;
9-
use std::collections::HashMap;
9+
use std::collections::{HashMap, HashSet};
1010

1111
pub(crate) const DEFAULT_SCALARS: &[&str] = &["ID", "String", "Int", "Float", "Boolean"];
1212

@@ -400,7 +400,13 @@ impl StoredInputType {
400400
}
401401
}
402402

403-
fn contains_type_without_indirection(&self, input_id: InputId, schema: &Schema) -> bool {
403+
fn contains_type_without_indirection(
404+
&self,
405+
input_id: InputId,
406+
schema: &Schema,
407+
visited_types: &mut HashSet<String>,
408+
) -> bool {
409+
visited_types.insert(self.name.clone());
404410
// The input type is recursive if any of its members contains it, without indirection
405411
self.fields.iter().any(|(_name, field_type)| {
406412
// the field is indirected, so no boxing is needed
@@ -417,8 +423,13 @@ impl StoredInputType {
417423

418424
let input = schema.get_input(field_input_id);
419425

426+
// no need to visit type twice (prevents infinite recursion)
427+
if visited_types.contains(&input.name) {
428+
return true;
429+
}
430+
420431
// we check if the other input contains this one (without indirection)
421-
input.contains_type_without_indirection(input_id, schema)
432+
input.contains_type_without_indirection(input_id, schema, visited_types)
422433
} else {
423434
// the field is not referring to an input type
424435
false
@@ -429,9 +440,9 @@ impl StoredInputType {
429440

430441
pub(crate) fn input_is_recursive_without_indirection(input_id: InputId, schema: &Schema) -> bool {
431442
let input = schema.get_input(input_id);
432-
input.contains_type_without_indirection(input_id, schema)
443+
let mut visited_types = HashSet::<String>::new();
444+
input.contains_type_without_indirection(input_id, schema, &mut visited_types)
433445
}
434-
435446
impl std::convert::From<graphql_parser::schema::Document> for Schema {
436447
fn from(ast: graphql_parser::schema::Document) -> Schema {
437448
graphql_parser_conversion::build_schema(ast)

0 commit comments

Comments
 (0)