Skip to content

Commit 096da1c

Browse files
committed
graphql-java#352 - fixed the bug where too many tokens are allowed as valid
1 parent 09d6dc0 commit 096da1c

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/main/java/graphql/parser/Parser.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
import org.antlr.v4.runtime.ANTLRInputStream;
77
import org.antlr.v4.runtime.BailErrorStrategy;
88
import org.antlr.v4.runtime.CommonTokenStream;
9+
import org.antlr.v4.runtime.Token;
910
import org.antlr.v4.runtime.atn.PredictionMode;
11+
import org.antlr.v4.runtime.misc.ParseCancellationException;
12+
13+
import java.util.List;
1014

1115
public class Parser {
1216

@@ -25,6 +29,21 @@ public Document parseDocument(String input) {
2529

2630
GraphqlAntlrToLanguage antlrToLanguage = new GraphqlAntlrToLanguage(tokens);
2731
antlrToLanguage.visitDocument(document);
32+
33+
Token stop = document.getStop();
34+
List<Token> allTokens = tokens.getTokens();
35+
if (stop != null && allTokens != null && !allTokens.isEmpty()) {
36+
Token last = allTokens.get(allTokens.size() - 1);
37+
//
38+
// do we have more tokens in the stream than we consumed in the parse?
39+
// if yes then its invalid. We make sure its the same channel
40+
boolean notEOF = last.getType() != Token.EOF;
41+
boolean lastGreaterThanDocument = last.getTokenIndex() > stop.getTokenIndex();
42+
boolean sameChannel = last.getChannel() == stop.getChannel();
43+
if (notEOF && lastGreaterThanDocument && sameChannel) {
44+
throw new ParseCancellationException("There are more tokens in the query that have not been consumed");
45+
}
46+
}
2847
return antlrToLanguage.result;
2948
}
3049
}

src/test/groovy/graphql/parser/ParserTest.groovy

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ class ParserTest extends Specification {
317317

318318
then:
319319
isEqual(helloField, new Field("hello", [new Argument("arg", new StringValue("hello, world"))]))
320-
helloField.comments.collect { c-> c.content } == [" this is some comment, which should be captured"]
320+
helloField.comments.collect { c -> c.content } == [" this is some comment, which should be captured"]
321321
}
322322

323323
@Unroll
@@ -408,4 +408,39 @@ class ParserTest extends Specification {
408408
'extend' | _
409409
'directive' | _
410410
}
411+
412+
def "#352 - incorrect parentheses are detected"() {
413+
given:
414+
def input = "{profile(id:117) {firstNames, lastNames, frontDegree}}}"
415+
416+
when:
417+
new Parser().parseDocument(input)
418+
419+
then:
420+
def exception = thrown(ParseCancellationException)
421+
exception != null
422+
}
423+
424+
def "#352 - lots of incorrect parentheses are detected"() {
425+
given:
426+
def input = "{profile(id:117) {firstNames, lastNames, frontDegree}}}}}}}}"
427+
428+
when:
429+
new Parser().parseDocument(input)
430+
431+
then:
432+
def exception = thrown(ParseCancellationException)
433+
exception != null
434+
}
435+
436+
def "#352 - comments don't count as unused"() {
437+
given:
438+
def input = "{profile(id:117) {firstNames, lastNames, frontDegree}} #trailing comments don't count"
439+
440+
when:
441+
new Parser().parseDocument(input)
442+
443+
then:
444+
noExceptionThrown()
445+
}
411446
}

0 commit comments

Comments
 (0)