Skip to content

Commit c631b0b

Browse files
authored
Merge pull request graphql-dotnet#233 from graphql-dotnet/argument-bug
Fix null reference on field without arguments
2 parents af551ee + 52c666c commit c631b0b

File tree

6 files changed

+56
-35
lines changed

6 files changed

+56
-35
lines changed

ILMerge.exe

-753 KB
Binary file not shown.

src/GraphQL.Tests/Execution/RegisteredInstanceTests.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ public ExecutionResult AssertQuery(
5959
var writtenResult = Writer.Write(runResult);
6060
var expectedResult = Writer.Write(expectedExecutionResult);
6161

62-
#if DEBUG
63-
Console.WriteLine(writtenResult);
64-
#endif
62+
//#if DEBUG
63+
// Console.WriteLine(writtenResult);
64+
//#endif
6565

6666
string additionalInfo = null;
6767

@@ -110,12 +110,6 @@ public void build_dynamic_schema()
110110
schema.Query = root;
111111
schema.RegisterTypes(person);
112112

113-
var printed = new SchemaPrinter(schema).Print();
114-
115-
#if DEBUG
116-
Console.WriteLine(printed);
117-
#endif
118-
119113
AssertQuerySuccess(
120114
schema,
121115
@"{ hero { name friends { name } } }",

src/GraphQL.Tests/Validation/KnownArgumentNamesTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ fragment argOnRequiredArg on Dog {
1515
");
1616
}
1717

18+
[Fact]
19+
public void no_args_are_known()
20+
{
21+
ShouldPassRule(@"
22+
fragment multipleArgs on ComplicatedArgs {
23+
noArgsField
24+
}
25+
");
26+
}
27+
1828
[Fact]
1929
public void multiple_args_are_known()
2030
{
@@ -84,6 +94,20 @@ dog @skip(if: true)
8494
");
8595
}
8696

97+
[Fact]
98+
public void field_with_no_args_given_arg_is_invalid()
99+
{
100+
ShouldFailRule(_ =>
101+
{
102+
_.Query = @"
103+
fragment multipleArgs on ComplicatedArgs {
104+
noArgsField(first: 1)
105+
}
106+
";
107+
_.Error(Rule.UnknownArgMessage("first", "noArgsField", "ComplicatedArgs", null), 3, 33);
108+
});
109+
}
110+
87111
[Fact]
88112
public void undirective_args_are_invalid()
89113
{

src/GraphQL.Tests/Validation/ValidationSchema.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ public class ComplicatedArgs : ObjectGraphType
197197
public ComplicatedArgs()
198198
{
199199
Name = "ComplicatedArgs";
200+
Field<StringGraphType>("noArgsField");
200201
Field<StringGraphType>(
201202
"intArgField",
202203
arguments: new QueryArguments(

src/GraphQL/Utilities/StringUtils.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,14 @@ public static string QuotedOrList(IEnumerable<string> items, int maxLength = 5)
8686
/// </summary>
8787
public static string[] SuggestionList(string input, IEnumerable<string> options)
8888
{
89+
if (options == null)
90+
{
91+
return new string[0];
92+
}
93+
8994
var optionsByDistance = new Dictionary<string, int>();
9095
var inputThreshold = input.Length / 2;
91-
options.Apply(t =>
96+
options?.Apply(t =>
9297
{
9398
var distance = DamerauLevenshteinDistance(input, t, inputThreshold);
9499
var threshold = Math.Max(inputThreshold, Math.Max(t.Length / 2, 1));
@@ -126,7 +131,7 @@ public static int DamerauLevenshteinDistance(string source, string target, int t
126131
// Return trivial case - difference in string lengths exceeds threshhold
127132
if (Math.Abs(length1 - length2) > threshold) { return int.MaxValue; }
128133

129-
// Ensure arrays [i] / length1 use shorter length
134+
// Ensure arrays [i] / length1 use shorter length
130135
if (length1 > length2)
131136
{
132137
Swap(ref target, ref source);

src/GraphQL/Validation/Rules/KnownArgumentNames.cs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Linq;
1+
using System.Linq;
32
using GraphQL.Language.AST;
43
using GraphQL.Utilities;
54

@@ -13,27 +12,25 @@ namespace GraphQL.Validation.Rules
1312
/// </summary>
1413
public class KnownArgumentNames : IValidationRule
1514
{
16-
public Func<string, string, string, string[], string> UnknownArgMessage =
17-
(argName, fieldName, type, suggestedArgs) =>
15+
public string UnknownArgMessage(string argName, string fieldName, string type, string[] suggestedArgs)
16+
{
17+
var message = $"Unknown argument \"{argName}\" on field \"{fieldName}\" of type \"{type}\".";
18+
if (suggestedArgs != null && suggestedArgs.Length > 0)
1819
{
19-
var message = $"Unknown argument \"{argName}\" on field \"{fieldName}\" of type \"{type}\".";
20-
if (suggestedArgs != null && suggestedArgs.Length > 0)
21-
{
22-
message += $"Did you mean {StringUtils.QuotedOrList(suggestedArgs)}";
23-
}
24-
return message;
25-
};
20+
message += $"Did you mean {StringUtils.QuotedOrList(suggestedArgs)}";
21+
}
22+
return message;
23+
}
2624

27-
public Func<string, string, string[], string> UnknownDirectiveArgMessage =
28-
(argName, directiveName, suggestedArgs) =>
25+
public string UnknownDirectiveArgMessage(string argName, string directiveName, string[] suggestedArgs)
26+
{
27+
var message = $"Unknown argument \"{argName}\" on directive \"{directiveName}\".";
28+
if (suggestedArgs != null && suggestedArgs.Length > 0)
2929
{
30-
var message = $"Unknown argument \"{argName}\" on directive \"{directiveName}\".";
31-
if (suggestedArgs != null && suggestedArgs.Length > 0)
32-
{
33-
message += $"Did you mean {StringUtils.QuotedOrList(suggestedArgs)}";
34-
}
35-
return message;
36-
};
30+
message += $"Did you mean {StringUtils.QuotedOrList(suggestedArgs)}";
31+
}
32+
return message;
33+
}
3734

3835
public INodeVisitor Validate(ValidationContext context)
3936
{
@@ -48,7 +45,7 @@ public INodeVisitor Validate(ValidationContext context)
4845
var fieldDef = context.TypeInfo.GetFieldDef();
4946
if (fieldDef != null)
5047
{
51-
var fieldArgDef = fieldDef.Arguments.Find(node.Name);
48+
var fieldArgDef = fieldDef.Arguments?.Find(node.Name);
5249
if (fieldArgDef == null)
5350
{
5451
var parentType = context.TypeInfo.GetParentType();
@@ -60,7 +57,7 @@ public INodeVisitor Validate(ValidationContext context)
6057
node.Name,
6158
fieldDef.Name,
6259
context.Print(parentType),
63-
StringUtils.SuggestionList(node.Name, fieldDef.Arguments.Select(q => q.Name))),
60+
StringUtils.SuggestionList(node.Name, fieldDef.Arguments?.Select(q => q.Name))),
6461
node));
6562
}
6663
}
@@ -69,7 +66,7 @@ public INodeVisitor Validate(ValidationContext context)
6966
var directive = context.TypeInfo.GetDirective();
7067
if (directive != null)
7168
{
72-
var directiveArgDef = directive.Arguments.Find(node.Name);
69+
var directiveArgDef = directive.Arguments?.Find(node.Name);
7370
if (directiveArgDef == null)
7471
{
7572
context.ReportError(new ValidationError(
@@ -78,7 +75,7 @@ public INodeVisitor Validate(ValidationContext context)
7875
UnknownDirectiveArgMessage(
7976
node.Name,
8077
directive.Name,
81-
StringUtils.SuggestionList(node.Name, directive.Arguments.Select(q => q.Name))),
78+
StringUtils.SuggestionList(node.Name, directive.Arguments?.Select(q => q.Name))),
8279
node));
8380
}
8481
}

0 commit comments

Comments
 (0)