17.x port - Stop DOS attacks by making the lexer stop early on evil input by bbakerman · Pull Request #2902 · graphql-java/graphql-java · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/pull_request.yml
10 changes: 9 additions & 1 deletion src/main/java/graphql/ParseAndValidate.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import graphql.language.Document;
import graphql.parser.InvalidSyntaxException;
import graphql.parser.Parser;
import graphql.parser.ParserOptions;
import graphql.schema.GraphQLSchema;
import graphql.validation.ValidationError;
import graphql.validation.Validator;

import java.util.List;

import static java.util.Optional.ofNullable;

/**
* This class allows you to parse and validate a graphql query without executing it. It will tell you
* if its syntactically valid and also semantically valid according to the graphql specification
Expand Down Expand Up @@ -42,8 +45,13 @@ public static ParseAndValidateResult parseAndValidate(GraphQLSchema graphQLSchem
*/
public static ParseAndValidateResult parse(ExecutionInput executionInput) {
try {
//
// we allow the caller to specify new parser options by context
ParserOptions parserOptions = executionInput.getGraphQLContext().get(ParserOptions.class);
// we use the query parser options by default if they are not specified
parserOptions = ofNullable(parserOptions).orElse(ParserOptions.getDefaultOperationParserOptions());
Parser parser = new Parser();
Document document = parser.parseDocument(executionInput.getQuery());
Document document = parser.parseDocument(executionInput.getQuery(),parserOptions);
return ParseAndValidateResult.newResult().document(document).variables(executionInput.getVariables()).build();
} catch (InvalidSyntaxException e) {
return ParseAndValidateResult.newResult().syntaxException(e).variables(executionInput.getVariables()).build();
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/graphql/parser/GraphqlAntlrToLanguage.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@
import static graphql.Assert.assertShouldNeverHappen;
import static graphql.collect.ImmutableKit.emptyList;
import static graphql.collect.ImmutableKit.map;
import static graphql.parser.Parser.CHANNEL_COMMENTS;
import static graphql.parser.Parser.CHANNEL_WHITESPACE;
import static graphql.parser.StringValueParsing.parseSingleQuotedString;
import static graphql.parser.StringValueParsing.parseTripleQuotedString;
import static java.util.Optional.ofNullable;

@Internal
public class GraphqlAntlrToLanguage {

private static final int CHANNEL_COMMENTS = 2;
private static final int CHANNEL_IGNORED_CHARS = 3;
private static final List<Comment> NO_COMMENTS = ImmutableKit.emptyList();
private final CommonTokenStream tokens;
private final MultiSourceReader multiSourceReader;
private final ParserOptions parserOptions;
Expand All @@ -96,7 +98,7 @@ public GraphqlAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiS
public GraphqlAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiSourceReader, ParserOptions parserOptions) {
this.tokens = tokens;
this.multiSourceReader = multiSourceReader;
this.parserOptions = parserOptions == null ? ParserOptions.getDefaultParserOptions() : parserOptions;
this.parserOptions = ofNullable(parserOptions).orElse(ParserOptions.getDefaultParserOptions());
}

public ParserOptions getParserOptions() {
Expand Down Expand Up @@ -790,12 +792,12 @@ private void addIgnoredChars(ParserRuleContext ctx, NodeBuilder nodeBuilder) {
}
Token start = ctx.getStart();
int tokenStartIndex = start.getTokenIndex();
List<Token> leftChannel = tokens.getHiddenTokensToLeft(tokenStartIndex, CHANNEL_IGNORED_CHARS);
List<Token> leftChannel = tokens.getHiddenTokensToLeft(tokenStartIndex, CHANNEL_WHITESPACE);
List<IgnoredChar> ignoredCharsLeft = mapTokenToIgnoredChar(leftChannel);

Token stop = ctx.getStop();
int tokenStopIndex = stop.getTokenIndex();
List<Token> rightChannel = tokens.getHiddenTokensToRight(tokenStopIndex, CHANNEL_IGNORED_CHARS);
List<Token> rightChannel = tokens.getHiddenTokensToRight(tokenStopIndex, CHANNEL_WHITESPACE);
List<IgnoredChar> ignoredCharsRight = mapTokenToIgnoredChar(rightChannel);

nodeBuilder.ignoredChars(new IgnoredChars(ignoredCharsLeft, ignoredCharsRight));
Expand Down
45 changes: 35 additions & 10 deletions src/main/java/graphql/parser/Parser.java
Loading