Skip to content

Conversation

@V0ldek
Copy link
Member

@V0ldek V0ldek commented Dec 21, 2025

Previously, when displaying a ParseError every underlying SyntaxError would be printed with the full query input as context. If the density of errors in the input was high this would effectively cause a quadratic blowup during printing.

It's probably unlikely inputs like this would be given by a user, but they do happen during fuzzing (when we're throwing long strings of essentially random characters at the parser) and could potentially be used as a DoS attack vector (intentionally supplying nonsensical large queries and forcing error messages to be sent back).

Any SyntaxError contains the actual error span
(which gets underlined in the output message) and the rest of the input is displayed as context. We will call the part before the error the pre-context, the part after the post-context, and the error part the underline.
We alleviate the quadratic blowup in two ways. First, in multiline input we now only display the lines that contain the underline. Second, if the first (or last) line of the error is excessively long and would print a very large pre-context (or post-context), we truncate the context by force to keep the total line length under a reasonable limit (error::display::MAX_ERROR_LINE_WIDTH).

Crucially, the SyntaxErrors never overlap, i.e. the underline parts are always disjoint. The fixes therefore guarantee that we will output at most the entire input, plus some constant overhead per error (limited by MAX_ERROR_LINE_WIDTH).

The logic to accomplish this is non-trivial, so now we have quite a bit of code dedicated to this rather exotic edge-case. Nonetheless, it ultimately makes the error reporting much more robust.

This is part of the investigation into fuzzing failures tracked at #749.

Issue

Related: #749

Checklist

All of these should be ticked off before you submit the PR.

  • I ran just verify locally and it succeeded.
  • Issue was given go ahead and is linked above OR I have included justification for a minor change.
  • Unit tests for my changes are included OR no functionality was changed.

Previously, when displaying a ParseError every underlying
SyntaxError would be printed with the full query input as context.
If the density of errors in the input was high this would effectively
cause a quadratic blowup during printing.

It's probably unlikely inputs like this would be given by a user,
but they do happen during fuzzing (when we're throwing long strings
of essentially random characters at the parser) and could potentially
be used as a DoS attack vector (intentionally supplying nonsensical
large queries and forcing error messages to be sent back).

Any SyntaxError contains the actual error span
(which gets underlined in the output message) and the rest of the
input is displayed as context. We will call the part before
the error the *pre-context*, the part after the *post-context*,
and the error part the *underline*.
We alleviate the quadratic blowup in two ways. First, in multiline
input we now only display the lines that contain the underline.
Second, if the first (or last) line of the error is excessively
long and would print a very large pre-context (or post-context),
we truncate the context by force to keep the total line length
under a reasonable limit (`error::display::MAX_ERROR_LINE_WIDTH`).

Crucially, the SyntaxErrors never overlap, i.e. the underline
parts are always disjoint. The fixes therefore guarantee that
we will output at most the entire input, plus some constant
overhead per error (limited by `MAX_ERROR_LINE_WIDTH`).

The logic to accomplish this is non-trivial, so now we have quite
a bit of code dedicated to this rather exotic edge-case.
Nonetheless, it ultimately makes the error reporting much more
robust.

This is part of the investigation into fuzzing failures tracked
at #749.
@V0ldek V0ldek force-pushed the v0ldek/fix-long-parser-error-messages branch from 8781b88 to 6d81a21 Compare December 21, 2025 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants