authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-06 15:54:25+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:49:01+02:00
loge6749167feb6841b3a81abb3863025d74dae9b7d
tree481cc5a54e4087191a539264c1c40f530875c171
parentb0738ef3e0354765b5aa1713d6313c8606c52f41
signaturelock-open Commit is signed but in an unrecognized format.

tools: enforce Block max depth in parser oracle


2 files changed, 16 insertions(+), 2 deletions(-)

lib/std/zig/parser_generated_oracle.zig+5-1
...@@ -10,7 +10,7 @@ const max_depth = 5;...@@ -10,7 +10,7 @@ const max_depth = 5;
10/// the grammar.10/// the grammar.
11/// Returns error.MaxDepth if more than `max_depth` levels of recursion/iteration are reached.11/// Returns error.MaxDepth if more than `max_depth` levels of recursion/iteration are reached.
12pub fn parse(source: []const u8) Error!bool {12pub fn parse(source: []const u8) Error!bool {
13 var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1 };13 var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1, .block_depth = 1 };
14 return p.parseRoot();14 return p.parseRoot();
15}15}
1616
...@@ -18,6 +18,7 @@ const Parser = struct {...@@ -18,6 +18,7 @@ const Parser = struct {
18 source: []const u8,18 source: []const u8,
19 i: usize,19 i: usize,
20 expr_depth: usize,20 expr_depth: usize,
21 block_depth: usize,
21 pub fn parseRoot(p: *Parser) Error!bool {22 pub fn parseRoot(p: *Parser) Error!bool {
22 return blk_0: {23 return blk_0: {
23 const pos_0 = p.i;24 const pos_0 = p.i;
...@@ -859,6 +860,9 @@ const Parser = struct {...@@ -859,6 +860,9 @@ const Parser = struct {
859 };860 };
860 }861 }
861 pub fn parseBlock(p: *Parser) Error!bool {862 pub fn parseBlock(p: *Parser) Error!bool {
863 if (p.block_depth >= max_depth) return error.MaxDepth;
864 p.block_depth += 1;
865 defer p.block_depth -= 1;
862 return blk_0: {866 return blk_0: {
863 const pos_0 = p.i;867 const pos_0 = p.i;
864 if (try p.parseLBRACE() and blk_1: {868 if (try p.parseLBRACE() and blk_1: {
tools/gen_parser_oracle.zig+11-1
...@@ -89,7 +89,7 @@ const Generator = struct {...@@ -89,7 +89,7 @@ const Generator = struct {
89 \\/// the grammar.89 \\/// the grammar.
90 \\/// Returns error.MaxDepth if more than `max_depth` levels of recursion/iteration are reached.90 \\/// Returns error.MaxDepth if more than `max_depth` levels of recursion/iteration are reached.
91 \\pub fn parse(source: []const u8) Error!bool {91 \\pub fn parse(source: []const u8) Error!bool {
92 \\ var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1 };92 \\ var p: Parser = .{ .source = source, .i = 0, .expr_depth = 1, .block_depth = 1 };
93 \\ return p.parseRoot();93 \\ return p.parseRoot();
94 \\}94 \\}
95 \\95 \\
...@@ -97,6 +97,7 @@ const Generator = struct {...@@ -97,6 +97,7 @@ const Generator = struct {
97 \\ source: []const u8,97 \\ source: []const u8,
98 \\ i: usize,98 \\ i: usize,
99 \\ expr_depth: usize,99 \\ expr_depth: usize,
100 \\ block_depth: usize,
100 \\101 \\
101 );102 );
102 for (g.p.getExtra(node.get(g.p).root)) |def| {103 for (g.p.getExtra(node.get(g.p).root)) |def| {
...@@ -110,6 +111,7 @@ const Generator = struct {...@@ -110,6 +111,7 @@ const Generator = struct {
110 const id = def.id.get(g.p).id;111 const id = def.id.get(g.p).id;
111 assert(g.suffix == 0);112 assert(g.suffix == 0);
112 try g.w.print("pub fn parse{s}(p: *Parser) Error!bool {{", .{id});113 try g.w.print("pub fn parse{s}(p: *Parser) Error!bool {{", .{id});
114 // The grammar can infinitely recurse through the Expr rule
113 if (mem.eql(u8, "Expr", id)) {115 if (mem.eql(u8, "Expr", id)) {
114 try g.w.print(116 try g.w.print(
115 \\if (p.expr_depth >= max_depth) return error.MaxDepth;117 \\if (p.expr_depth >= max_depth) return error.MaxDepth;
...@@ -117,6 +119,14 @@ const Generator = struct {...@@ -117,6 +119,14 @@ const Generator = struct {
117 \\defer p.expr_depth -= 1;119 \\defer p.expr_depth -= 1;
118 , .{});120 , .{});
119 }121 }
122 // The grammar can infinitely recurse through the Block rule
123 if (mem.eql(u8, "Block", id)) {
124 try g.w.print(
125 \\if (p.block_depth >= max_depth) return error.MaxDepth;
126 \\p.block_depth += 1;
127 \\defer p.block_depth -= 1;
128 , .{});
129 }
120 try g.w.writeAll("return ");130 try g.w.writeAll("return ");
121 try g.genExpr(def.expr);131 try g.genExpr(def.expr);
122 try g.w.writeAll(";}");132 try g.w.writeAll(";}");