diff --git a/lib/std/zig/parser_generated_oracle.zig b/lib/std/zig/parser_generated_oracle.zig index 65022c39394a3ec715d7cacc5673f10070f49767..0000d9c4eaa2da30f3f75d5f78247955a7d1bef6 100644 --- a/lib/std/zig/parser_generated_oracle.zig +++ b/lib/std/zig/parser_generated_oracle.zig @@ -10,7 +10,7 @@ const max_depth = 5; /// the grammar. /// Returns error.MaxDepth if more than `max_depth` levels of recursion/iteration are reached. pub fn parse(source: []const u8) Error!bool { - var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1 }; + var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1, .block_depth = 1 }; return p.parseRoot(); } @@ -18,6 +18,7 @@ const Parser = struct { source: []const u8, i: usize, expr_depth: usize, + block_depth: usize, pub fn parseRoot(p: *Parser) Error!bool { return blk_0: { const pos_0 = p.i; @@ -859,6 +860,9 @@ const Parser = struct { }; } pub fn parseBlock(p: *Parser) Error!bool { + if (p.block_depth >= max_depth) return error.MaxDepth; + p.block_depth += 1; + defer p.block_depth -= 1; return blk_0: { const pos_0 = p.i; if (try p.parseLBRACE() and blk_1: { diff --git a/tools/gen_parser_oracle.zig b/tools/gen_parser_oracle.zig index 0e6c2746f17aafe49a2f644d4d82c0af5cc3f556..9203aa3abc852e6a1e20b75250bf7d11750950c0 100644 --- a/tools/gen_parser_oracle.zig +++ b/tools/gen_parser_oracle.zig @@ -89,7 +89,7 @@ const Generator = struct { \\/// the grammar. \\/// Returns error.MaxDepth if more than `max_depth` levels of recursion/iteration are reached. \\pub fn parse(source: []const u8) Error!bool { - \\ var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1 }; + \\ var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1, .block_depth = 1 }; \\ return p.parseRoot(); \\} \\ @@ -97,6 +97,7 @@ const Generator = struct { \\ source: []const u8, \\ i: usize, \\ expr_depth: usize, + \\ block_depth: usize, \\ ); for (g.p.getExtra(node.get(g.p).root)) |def| { @@ -110,6 +111,7 @@ const Generator = struct { const id = def.id.get(g.p).id; assert(g.suffix == 0); try g.w.print("pub fn parse{s}(p: *Parser) Error!bool {{", .{id}); + // The grammar can infinitely recurse through the Expr rule if (mem.eql(u8, "Expr", id)) { try g.w.print( \\if (p.expr_depth >= max_depth) return error.MaxDepth; @@ -117,6 +119,14 @@ const Generator = struct { \\defer p.expr_depth -= 1; , .{}); } + // The grammar can infinitely recurse through the Block rule + if (mem.eql(u8, "Block", id)) { + try g.w.print( + \\if (p.block_depth >= max_depth) return error.MaxDepth; + \\p.block_depth += 1; + \\defer p.block_depth -= 1; + , .{}); + } try g.w.writeAll("return "); try g.genExpr(def.expr); try g.w.writeAll(";}");