diff --git a/doc/langref/grammar.peg b/doc/langref/grammar.peg index 819e391680d8ed393cb823e1cbd9781e54ff457b..06a01d86f67c6bcc9d7f924e05b870dd0d800760 100644 --- a/doc/langref/grammar.peg +++ b/doc/langref/grammar.peg @@ -527,13 +527,14 @@ NUMBERLITERAL / skip [0-9] digit_float* -STRINGLITERALSINGLE <- skip ["] string_char* ["] +string <- ["] string_char* ["] +STRINGLITERALSINGLE <- skip string STRINGLITERAL - <- STRINGLITERALSINGLE + <- skip string / (skip line_string)+ IDENTIFIER <- skip !keyword [A-Za-z_] [A-Za-z0-9_]* - / skip '@' STRINGLITERALSINGLE + / skip '@' string BUILTINIDENTIFIER <- skip '@'[A-Za-z_][A-Za-z0-9_]* diff --git a/lib/std/zig/parser_fuzz.zig b/lib/std/zig/parser_fuzz.zig index f42099142b7548879d18319fabd7481b7dfa6307..e55e1d833021b9b402f4f5f57e64f07b438e89d3 100644 --- a/lib/std/zig/parser_fuzz.zig +++ b/lib/std/zig/parser_fuzz.zig @@ -78,6 +78,14 @@ test "fn container field" { try checkAgainstOracle("fn()0"); } +// Found using AFL++ +test "at newline string" { + 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 6908f1fbe6daa8c698989e6e3c0a8d236f5ed2f9..a8d0b930c9674bf042e54597d0496a57471eec76 100644 --- a/lib/std/zig/parser_generated_oracle.zig +++ b/lib/std/zig/parser_generated_oracle.zig @@ -2818,10 +2818,10 @@ const Parser = struct { break :blk_0 false; }; } - pub fn parseSTRINGLITERALSINGLE(p: *Parser) bool { + pub fn parsestring(p: *Parser) bool { return blk_0: { const pos_0 = p.i; - if (p.parseskip() and (p.i < p.source.len and switch (p.source[p.i]) { + if ((p.i < p.source.len and switch (p.source[p.i]) { '"'...'"', => blk_1: { p.i += 1; @@ -2843,10 +2843,18 @@ const Parser = struct { break :blk_0 false; }; } + pub fn parseSTRINGLITERALSINGLE(p: *Parser) bool { + return blk_0: { + const pos_0 = p.i; + if (p.parseskip() and p.parsestring()) break :blk_0 true; + p.i = pos_0; + break :blk_0 false; + }; + } pub fn parseSTRINGLITERAL(p: *Parser) bool { return blk_0: { const pos_0 = p.i; - if (p.parseSTRINGLITERALSINGLE()) break :blk_0 true; + if (p.parseskip() and p.parsestring()) break :blk_0 true; p.i = pos_0; if (blk_1: { var match_1 = false; @@ -2902,7 +2910,7 @@ const Parser = struct { break :blk_1 true; } break :blk_1 false; - } and p.parseSTRINGLITERALSINGLE()) break :blk_0 true; + } and p.parsestring()) break :blk_0 true; p.i = pos_0; break :blk_0 false; };