Skip to content

Defer unescaping in Parser until tokens are used as values#1244

Merged
brharrington merged 1 commit into
Netflix:mainfrom
brharrington:fix-parser-unescape-ordering
Jun 12, 2026
Merged

Defer unescaping in Parser until tokens are used as values#1244
brharrington merged 1 commit into
Netflix:mainfrom
brharrington:fix-parser-unescape-ordering

Conversation

@brharrington

Copy link
Copy Markdown
Contributor

The query/data expression parser unescaped each comma-separated token up front, before deciding whether it was a structural token (a parenthesis or a :operator). As a result an escaped special character that was intended as data, such as ( or :in, was unescaped to ( or :in and then mistaken for syntax. Depending on the expression this either threw invalid query expression (a lone escaped paren or a top-level escaped operator) or produced a structurally different query. In a streaming context a subscription whose expression fails to parse silently matches nothing, so streaming results could diverge from the backend.

Match structural tokens against the raw token and only unescape when a token is stored as a value (the scalar push and list members). This mirrors the Atlas server parser (Interpreter.nextStep / popAndPushList).

Also align escaping with the server so values round-trip: escape : in addition to comma and whitespace, and escape a standalone (/) token. Add a fast path to unescape to avoid allocating when there is nothing to do.

The query/data expression parser unescaped each comma-separated token up
front, before deciding whether it was a structural token (a parenthesis or
a `:operator`). As a result an escaped special character that was intended
as data, such as `(` or `:in`, was unescaped to `(` or `:in` and
then mistaken for syntax. Depending on the expression this either threw
`invalid query expression` (a lone escaped paren or a top-level escaped
operator) or produced a structurally different query. In a streaming
context a subscription whose expression fails to parse silently matches
nothing, so streaming results could diverge from the backend.

Match structural tokens against the raw token and only unescape when a
token is stored as a value (the scalar push and list members). This mirrors
the Atlas server parser (Interpreter.nextStep / popAndPushList).

Also align escaping with the server so values round-trip: escape `:` in
addition to comma and whitespace, and escape a standalone `(`/`)` token.
Add a fast path to unescape to avoid allocating when there is nothing to do.
@brharrington brharrington added this to the 1.9.10 milestone Jun 12, 2026
@brharrington brharrington merged commit 2b94fae into Netflix:main Jun 12, 2026
1 check passed
@brharrington brharrington deleted the fix-parser-unescape-ordering branch June 12, 2026 03:17
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.

1 participant