diff --git a/doc/langref/grammar.peg b/doc/langref/grammar.peg index 9d290cf3a1d2c7fef1ab4a6fd5f0aa909ba096e8..a571b430aa06c231d1f82c8faf68d29b533e7a15 100644 --- a/doc/langref/grammar.peg +++ b/doc/langref/grammar.peg @@ -378,14 +378,14 @@ SuffixOp <- LBRACKET Expr (DOT2 (Expr / !ExprPrefix) (COLON Expr)?)? RBRACKET / DOT IDENTIFIER / DOTASTERISK - / DOTQUESTIONMARK + / DOT QUESTIONMARK / FnCallArguments SuffixOpPrefix <- LBRACKET / DOT IDENTIFIER / DOTASTERISK - / DOTQUESTIONMARK + / DOT QUESTIONMARK / LPAREN FnCallArguments <- LPAREN ExprList RPAREN @@ -554,11 +554,10 @@ CARET <- skip '^' ![=] CARETEQUAL <- skip '^=' COLON <- skip ':' COMMA <- skip ',' -DOT <- skip '.' ![*.?] +DOT <- skip '.' ![*.] DOT2 <- skip '..' ![.] DOT3 <- skip '...' DOTASTERISK <- skip '.*' -DOTQUESTIONMARK <- skip '.?' EQUAL <- skip '=' ![>=] EQUALEQUAL <- skip '==' EQUALRARROW <- skip '=>' diff --git a/lib/std/zig/Parse.zig b/lib/std/zig/Parse.zig index 8b694eea05c9f39a00ff06aa43b314073d0e98bc..6fc64faa8358000748947d1a047a98dc06e7d4dd 100644 --- a/lib/std/zig/Parse.zig +++ b/lib/std/zig/Parse.zig @@ -3069,7 +3069,7 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { /// <- LBRACKET Expr (DOT2 Expr? (COLON Expr)?)? RBRACKET /// / DOT IDENTIFIER /// / DOTASTERISK -/// / DOTQUESTIONMARK +/// / DOT QUESTIONMARK /// / FnCallArguments /// /// FnCallArguments <- LPAREN ExprList RPAREN diff --git a/lib/std/zig/parser_fuzz.zig b/lib/std/zig/parser_fuzz.zig index 1cf5818b4b0b01e197f3253c2b3fd217b7b848e3..75b17d60a03e01816dc8947530d159c431570b7c 100644 --- a/lib/std/zig/parser_fuzz.zig +++ b/lib/std/zig/parser_fuzz.zig @@ -93,6 +93,11 @@ test "string lit" { ); } +// Found using AFL++ +test "dot question" { + try checkAgainstOracle("0. ?"); +} + 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 2646ce702c3f83c612f0454bb2619209d292da09..264e19b649deed5706d540a8c0accdb631dfca63 100644 --- a/lib/std/zig/parser_generated_oracle.zig +++ b/lib/std/zig/parser_generated_oracle.zig @@ -1805,7 +1805,7 @@ const Parser = struct { p.i = pos_0; if (p.parseDOTASTERISK()) break :blk_0 true; p.i = pos_0; - if (p.parseDOTQUESTIONMARK()) break :blk_0 true; + if (p.parseDOT() and p.parseQUESTIONMARK()) break :blk_0 true; p.i = pos_0; if (p.parseFnCallArguments()) break :blk_0 true; p.i = pos_0; @@ -1821,7 +1821,7 @@ const Parser = struct { p.i = pos_0; if (p.parseDOTASTERISK()) break :blk_0 true; p.i = pos_0; - if (p.parseDOTQUESTIONMARK()) break :blk_0 true; + if (p.parseDOT() and p.parseQUESTIONMARK()) break :blk_0 true; p.i = pos_0; if (p.parseLPAREN()) break :blk_0 true; p.i = pos_0; @@ -3211,7 +3211,6 @@ const Parser = struct { const match_1 = (p.i < p.source.len and switch (p.source[p.i]) { '*'...'*', '.'...'.', - '?'...'?', => blk_2: { p.i += 1; break :blk_2 true; @@ -3279,20 +3278,6 @@ const Parser = struct { break :blk_0 false; }; } - pub fn parseDOTQUESTIONMARK(p: *Parser) bool { - return blk_0: { - const pos_0 = p.i; - if (p.parseskip() and 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; - break :blk_0 false; - }; - } pub fn parseEQUAL(p: *Parser) bool { return blk_0: { const pos_0 = p.i;