authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-06-18 14:39:41+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:48:59+02:00
log78a196d04fb2c3a978fabec4c8c236f09add591e
tree9bb21608330e35faad22d176b46869b95fb97e8f
parentec04ae6e0003a7fd35782dbc26c89f9905119aee
signaturelock-open Commit is signed but in an unrecognized format.

grammar: fix escaped backslash tokenization


3 files changed, 29 insertions(+), 2 deletions(-)

doc/langref/grammar.peg+6-2
......@@ -483,19 +483,23 @@ non_control_utf8 <- [\040-\176\200-\377]
483483#
484484# char_char
485485# <- multibyte_utf8
486# / "\\\\"
486487# / "\\'"
487488# / !['] non_control_ascii
488489# string_char
489490# <- multibyte_utf8
491# / '\\\\'
490492# / '\\"'
491493# / !["] non_control_ascii
492494
493495char_char
494 <- "\\'"
496 <- "\\\\"
497 / "\\'"
495498 / !['] non_control_utf8
496499
497500string_char
498 <- '\\"'
501 <- '\\\\'
502 / '\\"'
499503 / !["] non_control_utf8
500504
501505
lib/std/zig/parser_fuzz.zig+7
......@@ -86,6 +86,13 @@ test "at newline string" {
8686 );
8787}
8888
89// Found using AFL++
90test "string lit" {
91 try checkAgainstOracle(
92 \\"\\"
93 );
94}
95
8996fn checkAgainstOracle(source: [:0]const u8) !void {
9097 var fba_buf: [1 << 18]u8 = undefined;
9198 var fba: std.heap.FixedBufferAllocator = .init(&fba_buf);
lib/std/zig/parser_generated_oracle.zig+16
......@@ -2362,6 +2362,14 @@ const Parser = struct {
23622362 pub fn parsechar_char(p: *Parser) bool {
23632363 return blk_0: {
23642364 const pos_0 = p.i;
2365 if (blk_1: {
2366 if (std.mem.startsWith(u8, p.source[p.i..], "\\\\")) {
2367 p.i += 2;
2368 break :blk_1 true;
2369 }
2370 break :blk_1 false;
2371 }) break :blk_0 true;
2372 p.i = pos_0;
23652373 if (blk_1: {
23662374 if (std.mem.startsWith(u8, p.source[p.i..], "\\'")) {
23672375 p.i += 2;
......@@ -2390,6 +2398,14 @@ const Parser = struct {
23902398 pub fn parsestring_char(p: *Parser) bool {
23912399 return blk_0: {
23922400 const pos_0 = p.i;
2401 if (blk_1: {
2402 if (std.mem.startsWith(u8, p.source[p.i..], "\\\\")) {
2403 p.i += 2;
2404 break :blk_1 true;
2405 }
2406 break :blk_1 false;
2407 }) break :blk_0 true;
2408 p.i = pos_0;
23932409 if (blk_1: {
23942410 if (std.mem.startsWith(u8, p.source[p.i..], "\\\"")) {
23952411 p.i += 2;