You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(parser,compiler): fix string serialization bugs found by fuzzing (#774)
* fuzz: add a fuzz target for string encoding/parsing
* Update to use compiler serialization
* Fix serializing single-line strings with leading whitespace
When parsing a block string, the first line does not affect the common
indent, as it would normally have no indent at all. But when
serializing a string to a block string, the first line *is* important,
namely for a single-line string that starts with whitespace.
Assume a text like this:
```
Starts with "spaces"
```
If we skip the first line, the common indent is detected as 0,
producing this output:
```graphql
"""
Starts with "spaces"
"""
```
Now when reparsing, the common indent is detected as 4, and you get
back:
```
Starts with "spaces"
```
which is wrong.
* Add failing test for \\""" in string
* enable debug log in fuzz test
* fix(lexer): lex \\""" as \ + \""" in block strings
Backslash is not special in block strings except in the exact sequence
`\"""`. So if you write `\\"""`, that sequence should still be treated
as the escape sequence for `"""`. This patch fixes that.
Previously, we would return to the BlockStringLiteral state on the
second `\`, and interpret the `"""` as the end of the string.
* fix rebase mistake
* changelogs
* pr number
source_text: "type Query {\n \"LF: a\\nb\"\n f1: Int\n\n \"CRLF: a\\r\\nb\"\n f2: Int\n\n \"\"\"\n a\n\n b\n \n\n \"\"\"\n f3: Int\n\n \"a \\\"b\\\" c\"\n f4: Int\n\n \"\"\"a \\\"\"\"b\\\"\"\" c\"\"\"\n f5: Int\n\n \"\"\"\n regex: \\d+\n \"\"\"\n f6: Int\n\n \"\\nLeading empty line to preserve\"\n f7: Int\n\n \" \\nLeading whitespace-only line to preserve\"\n f8: Int\n\n \"Trailing empty line to preserve\\n\"\n f9: Int\n\n \"Trailing whitespace-only line to preserve\\n\\t\"\n f10: Int\n\n f11(arg: String = \"a\\nb\"): Int\n\n f12(arg: String = \"a \\\"b\\\" c\"): Int\n\n f13(arg: String = \"regex: \\\\d+\"): Int\n\n \"Trailing backslash \\\\\"\n f14: Int\n\n \"Trailing quote\\\"\"\n f15: Int\n\n \" Leading whitespace on a single line to preserve\"\n f16: Int\n\n \" Leading whitespace in multi-line string to preserve\\nNo leading whitespace on second line\"\n f17: Int\n\n \"\\n Leading empty line + indent to preserve\"\n f18: Int\n\n \"When serialized as a block string, \\\\\\\"\\\"\\\" outputs \\\\ in front of the escaped triple quote\"\n f19: Int\n}\n",
10
10
},
11
11
},
12
12
schema_definition: SchemaDefinition {
@@ -42,7 +42,7 @@ Schema {
42
42
"Boolean": built_in_type!("Boolean"),
43
43
"ID": built_in_type!("ID"),
44
44
"Query": Object(
45
-
0..602 @38 ObjectType {
45
+
0..947 @38 ObjectType {
46
46
description: None,
47
47
name: "Query",
48
48
implements_interfaces: {},
@@ -294,6 +294,62 @@ Schema {
294
294
directives: [],
295
295
},
296
296
},
297
+
"f16": Component {
298
+
origin: Definition,
299
+
node: 604..667 @38 FieldDefinition {
300
+
description: Some(
301
+
" Leading whitespace on a single line to preserve",
302
+
),
303
+
name: "f16",
304
+
arguments: [],
305
+
ty: Named(
306
+
"Int",
307
+
),
308
+
directives: [],
309
+
},
310
+
},
311
+
"f17": Component {
312
+
origin: Definition,
313
+
node: 671..776 @38 FieldDefinition {
314
+
description: Some(
315
+
" Leading whitespace in multi-line string to preserve\nNo leading whitespace on second line",
316
+
),
317
+
name: "f17",
318
+
arguments: [],
319
+
ty: Named(
320
+
"Int",
321
+
),
322
+
directives: [],
323
+
},
324
+
},
325
+
"f18": Component {
326
+
origin: Definition,
327
+
node: 780..837 @38 FieldDefinition {
328
+
description: Some(
329
+
"\n Leading empty line + indent to preserve",
330
+
),
331
+
name: "f18",
332
+
arguments: [],
333
+
ty: Named(
334
+
"Int",
335
+
),
336
+
directives: [],
337
+
},
338
+
},
339
+
"f19": Component {
340
+
origin: Definition,
341
+
node: 841..945 @38 FieldDefinition {
342
+
description: Some(
343
+
"When serialized as a block string, \\\"\"\" outputs \\ in front of the escaped triple quote",
source_text: "type Query {\n \"LF: a\\nb\"\n f1: Int\n\n \"CRLF: a\\r\\nb\"\n f2: Int\n\n \"\"\"\n a\n\n b\n \n\n \"\"\"\n f3: Int\n\n \"a \\\"b\\\" c\"\n f4: Int\n\n \"\"\"a \\\"\"\"b\\\"\"\" c\"\"\"\n f5: Int\n\n \"\"\"\n regex: \\d+\n \"\"\"\n f6: Int\n\n \"\\nLeading empty line to preserve\"\n f7: Int\n\n \" \\nLeading whitespace-only line to preserve\"\n f8: Int\n\n \"Trailing empty line to preserve\\n\"\n f9: Int\n\n \"Trailing whitespace-only line to preserve\\n\\t\"\n f10: Int\n\n f11(arg: String = \"a\\nb\"): Int\n\n f12(arg: String = \"a \\\"b\\\" c\"): Int\n\n f13(arg: String = \"regex: \\\\d+\"): Int\n\n \"Trailing backslash \\\\\"\n f14: Int\n\n \"Trailing quote\\\"\"\n f15: Int\n\n \" Leading whitespace on a single line to preserve\"\n f16: Int\n\n \" Leading whitespace in multi-line string to preserve\\nNo leading whitespace on second line\"\n f17: Int\n\n \"\\n Leading empty line + indent to preserve\"\n f18: Int\n\n \"When serialized as a block string, \\\\\\\"\\\"\\\" outputs \\\\ in front of the escaped triple quote\"\n f19: Int\n}\n",
0 commit comments