Mirror: The spec-compliant minimum of client-side GraphQL.

Fix string and block string matches being too eager (#17)

* Add test cases for strings greedily matching

* Fix blockStringRe and stringRe eagerly parsing

* Add changeset

authored by kitten.sh and committed by GitHub 3c394901 66f7686d

Changed files
+31 -2
.changeset
src
+5
.changeset/loud-countries-mix.md
··· 1 + --- 2 + '@0no-co/graphql.web': patch 3 + --- 4 + 5 + Fix string and block string matches eagerly matching past the end boundary of strings and ignoring escaped closing characters. In certain cases, `"""` and `"` boundaries would be skipped if any other string boundary follows in the input document.
+24
src/__tests__/parser.test.ts
··· 478 478 value: '\t\t', 479 479 block: false, 480 480 }); 481 + 482 + expect(parseValue('" \\" "')).toEqual({ 483 + kind: Kind.STRING, 484 + value: ' " ', 485 + block: false, 486 + }); 487 + 488 + expect(parseValue('"x" "x"')).toEqual({ 489 + kind: Kind.STRING, 490 + value: 'x', 491 + block: false, 492 + }); 481 493 }); 482 494 483 495 it('parses objects', () => { ··· 546 558 expect(parseValue('"""\n\n first\n second\n"""')).toEqual({ 547 559 kind: Kind.STRING, 548 560 value: 'first\nsecond', 561 + block: true, 562 + }); 563 + 564 + expect(parseValue('""" \\""" """')).toEqual({ 565 + kind: Kind.STRING, 566 + value: ' """ ', 567 + block: true, 568 + }); 569 + 570 + expect(parseValue('"""x""" """x"""')).toEqual({ 571 + kind: Kind.STRING, 572 + value: 'x', 549 573 block: true, 550 574 }); 551 575 });
+2 -2
src/parser.ts
··· 86 86 const floatPartRe = /(?:\.\d+)?[eE][+-]?\d+|\.\d+/y; 87 87 88 88 const complexStringRe = /\\/g; 89 - const blockStringRe = /"""(?:[\s\S]+(?="""))?"""/y; 90 - const stringRe = /"(?:[^"\r\n]+)?"/y; 89 + const blockStringRe = /"""(?:[\s\S]*?[^\\])?"""/y; 90 + const stringRe = /"(?:[^\r\n]*?[^\\])?"/y; 91 91 92 92 function value(constant: true): ast.ConstValueNode; 93 93 function value(constant: boolean): ast.ValueNode;