@@ -36,6 +36,7 @@ public class ParserOptions {
3636 .captureIgnoredChars (false )
3737 .captureSourceLocation (true )
3838 .captureLineComments (true )
39+ .readerTrackData (true )
3940 .maxTokens (MAX_QUERY_TOKENS ) // to prevent a billion laughs style attacks, we set a default for graphql-java
4041 .maxWhitespaceTokens (MAX_WHITESPACE_TOKENS )
4142 .build ();
@@ -44,6 +45,7 @@ public class ParserOptions {
4445 .captureIgnoredChars (false )
4546 .captureSourceLocation (true )
4647 .captureLineComments (false ) // #comments are not useful in query parsing
48+ .readerTrackData (true )
4749 .maxTokens (MAX_QUERY_TOKENS ) // to prevent a billion laughs style attacks, we set a default for graphql-java
4850 .maxWhitespaceTokens (MAX_WHITESPACE_TOKENS )
4951 .build ();
@@ -52,6 +54,7 @@ public class ParserOptions {
5254 .captureIgnoredChars (false )
5355 .captureSourceLocation (true )
5456 .captureLineComments (true ) // #comments are useful in SDL parsing
57+ .readerTrackData (true )
5558 .maxTokens (Integer .MAX_VALUE ) // we are less worried about a billion laughs with SDL parsing since the call path is not facing attackers
5659 .maxWhitespaceTokens (Integer .MAX_VALUE )
5760 .build ();
@@ -154,6 +157,7 @@ public static void setDefaultSdlParserOptions(ParserOptions options) {
154157 private final boolean captureIgnoredChars ;
155158 private final boolean captureSourceLocation ;
156159 private final boolean captureLineComments ;
160+ private final boolean readerTrackData ;
157161 private final int maxTokens ;
158162 private final int maxWhitespaceTokens ;
159163 private final ParsingListener parsingListener ;
@@ -162,6 +166,7 @@ private ParserOptions(Builder builder) {
162166 this .captureIgnoredChars = builder .captureIgnoredChars ;
163167 this .captureSourceLocation = builder .captureSourceLocation ;
164168 this .captureLineComments = builder .captureLineComments ;
169+ this .readerTrackData = builder .readerTrackData ;
165170 this .maxTokens = builder .maxTokens ;
166171 this .maxWhitespaceTokens = builder .maxWhitespaceTokens ;
167172 this .parsingListener = builder .parsingListener ;
@@ -204,6 +209,15 @@ public boolean isCaptureLineComments() {
204209 return captureLineComments ;
205210 }
206211
212+ /**
213+ * Controls whether the underlying {@link MultiSourceReader} should track previously read data or not.
214+ *
215+ * @return true if {@link MultiSourceReader} should track data in memory.
216+ */
217+ public boolean isReaderTrackData () {
218+ return readerTrackData ;
219+ }
220+
207221 /**
208222 * A graphql hacking vector is to send nonsensical queries that burn lots of parsing CPU time and burns
209223 * memory representing a document that won't ever execute. To prevent this you can set a maximum number of parse
@@ -245,6 +259,7 @@ public static class Builder {
245259 private boolean captureIgnoredChars = false ;
246260 private boolean captureSourceLocation = true ;
247261 private boolean captureLineComments = true ;
262+ private boolean readerTrackData = true ;
248263 private int maxTokens = MAX_QUERY_TOKENS ;
249264 private ParsingListener parsingListener = ParsingListener .NOOP ;
250265 private int maxWhitespaceTokens = MAX_WHITESPACE_TOKENS ;
@@ -276,6 +291,11 @@ public Builder captureLineComments(boolean captureLineComments) {
276291 return this ;
277292 }
278293
294+ public Builder readerTrackData (boolean readerTrackData ) {
295+ this .readerTrackData = readerTrackData ;
296+ return this ;
297+ }
298+
279299 public Builder maxTokens (int maxTokens ) {
280300 this .maxTokens = maxTokens ;
281301 return this ;
0 commit comments