From 78a196d04fb2c3a978fabec4c8c236f09add591e Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Thu, 18 Jun 2026 14:39:41 +0200 Subject: [PATCH] grammar: fix escaped backslash tokenization --- doc/langref/grammar.peg | 8 ++++++-- lib/std/zig/parser_fuzz.zig | 7 +++++++ lib/std/zig/parser_generated_oracle.zig | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/doc/langref/grammar.peg b/doc/langref/grammar.peg index 06a01d86f67c6bcc9d7f924e05b870dd0d800760..9d290cf3a1d2c7fef1ab4a6fd5f0aa909ba096e8 100644 --- a/doc/langref/grammar.peg +++ b/doc/langref/grammar.peg @@ -483,19 +483,23 @@ non_control_utf8 <- [\040-\176\200-\377] # # char_char # <- multibyte_utf8 +# / "\\\\" # / "\\'" # / !['] non_control_ascii # string_char # <- multibyte_utf8 +# / '\\\\' # / '\\"' # / !["] non_control_ascii char_char - <- "\\'" + <- "\\\\" + / "\\'" / !['] non_control_utf8 string_char - <- '\\"' + <- '\\\\' + / '\\"' / !["] non_control_utf8 diff --git a/lib/std/zig/parser_fuzz.zig b/lib/std/zig/parser_fuzz.zig index e55e1d833021b9b402f4f5f57e64f07b438e89d3..1cf5818b4b0b01e197f3253c2b3fd217b7b848e3 100644 --- a/lib/std/zig/parser_fuzz.zig +++ b/lib/std/zig/parser_fuzz.zig @@ -86,6 +86,13 @@ test "at newline string" { ); } +// Found using AFL++ +test "string lit" { + try checkAgainstOracle( + \\"\\" + ); +} + fn checkAgainstOracle(source: [:0]const u8) !void { var fba_buf: [1 << 18]u8 = undefined; var fba: std.heap.FixedBufferAllocator = .init(&fba_buf); diff --git a/lib/std/zig/parser_generated_oracle.zig b/lib/std/zig/parser_generated_oracle.zig index a8d0b930c9674bf042e54597d0496a57471eec76..2646ce702c3f83c612f0454bb2619209d292da09 100644 --- a/lib/std/zig/parser_generated_oracle.zig +++ b/lib/std/zig/parser_generated_oracle.zig @@ -2362,6 +2362,14 @@ const Parser = struct { pub fn parsechar_char(p: *Parser) bool { return blk_0: { const pos_0 = p.i; + if (blk_1: { + if (std.mem.startsWith(u8, p.source[p.i..], "\\\\")) { + p.i += 2; + break :blk_1 true; + } + break :blk_1 false; + }) break :blk_0 true; + p.i = pos_0; if (blk_1: { if (std.mem.startsWith(u8, p.source[p.i..], "\\'")) { p.i += 2; @@ -2390,6 +2398,14 @@ const Parser = struct { pub fn parsestring_char(p: *Parser) bool { return blk_0: { const pos_0 = p.i; + if (blk_1: { + if (std.mem.startsWith(u8, p.source[p.i..], "\\\\")) { + p.i += 2; + break :blk_1 true; + } + break :blk_1 false; + }) break :blk_0 true; + p.i = pos_0; if (blk_1: { if (std.mem.startsWith(u8, p.source[p.i..], "\\\"")) { p.i += 2; -- 2.54.0