From a2900f88b4cf1034851aeedfa987a6191a83426b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Ram=C3=B3n?= Date: Sat, 5 Aug 2017 14:13:58 -0500 Subject: [PATCH] Fix nil panic in UniqueOperationNamesRule with two anonymous operations node.Name is nil when the operation is anonymous. Use the parent AST node instead in this case. Found with go-fuzz. Commit: titanous/graphql@ab875bc40a7ef41d8510653301ecdf40f594fd52 --- rules.go | 10 +++++++--- rules_unique_operation_names_test.go | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/rules.go b/rules.go index b234cf71..a269bee8 100644 --- a/rules.go +++ b/rules.go @@ -1517,7 +1517,7 @@ func UniqueInputFieldNamesRule(context *ValidationContext) *ValidationRuleInstan // // A GraphQL document is only valid if all defined operations have unique names. func UniqueOperationNamesRule(context *ValidationContext) *ValidationRuleInstance { - knownOperationNames := map[string]*ast.Name{} + knownOperationNames := make(map[string]ast.Node) visitorOpts := &visitor.VisitorOptions{ KindFuncMap: map[string]visitor.NamedVisitFuncs{ @@ -1528,14 +1528,18 @@ func UniqueOperationNamesRule(context *ValidationContext) *ValidationRuleInstanc if node.Name != nil { operationName = node.Name.Value } + var errNode ast.Node = node + if node.Name != nil { + errNode = node.Name + } if nameAST, ok := knownOperationNames[operationName]; ok { reportError( context, fmt.Sprintf(`There can only be one operation named "%v".`, operationName), - []ast.Node{nameAST, node.Name}, + []ast.Node{nameAST, errNode}, ) } else { - knownOperationNames[operationName] = node.Name + knownOperationNames[operationName] = errNode } } return visitor.ActionSkip, nil diff --git a/rules_unique_operation_names_test.go b/rules_unique_operation_names_test.go index 8903cdcb..265c3f42 100644 --- a/rules_unique_operation_names_test.go +++ b/rules_unique_operation_names_test.go @@ -102,3 +102,9 @@ func TestValidate_UniqueOperationNames_MultipleOperationsOfSameNameOfDifferentTy testutil.RuleError(`There can only be one operation named "Foo".`, 2, 13, 5, 20), }) } + +func TestValidate_UniqueOperationNames_MultipleAnonymousOperations(t *testing.T) { + testutil.ExpectFailsRule(t, graphql.UniqueOperationNamesRule, `{a}{b}`, []gqlerrors.FormattedError{ + testutil.RuleError(`There can only be one operation named "".`, 1, 1, 1, 4), + }) +}