authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-01 21:07:07+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-01 16:09:57-08:00
log7b5b7bda87dc4121e2942042d19fd375c73f90e5
treed4e28868de6b2d6de9b81914773020c65ad55a71
parentcd7c870bd81391dd97c5c75eb3910382ba7280a1

parser: fix infinite loop on missing comma in param list


2 files changed, 24 insertions(+), 20 deletions(-)

lib/std/zig/parse.zig+12-20
......@@ -3714,7 +3714,6 @@ const Parser = struct {
37143714 if (p.eatToken(.r_paren)) |_| {
37153715 return SmallSpan{ .zero_or_one = 0 };
37163716 }
3717 continue;
37183717 },
37193718 .r_paren => return SmallSpan{ .zero_or_one = 0 },
37203719 else => {
......@@ -3728,14 +3727,7 @@ const Parser = struct {
37283727
37293728 const param_two = while (true) {
37303729 switch (p.token_tags[p.nextToken()]) {
3731 .comma => {
3732 if (p.eatToken(.r_paren)) |_| {
3733 return SmallSpan{ .zero_or_one = param_one };
3734 }
3735 const param = try p.expectParamDecl();
3736 if (param != 0) break param;
3737 continue;
3738 },
3730 .comma => {},
37393731 .r_paren => return SmallSpan{ .zero_or_one = param_one },
37403732 .colon, .r_brace, .r_bracket => {
37413733 p.tok_i -= 1;
......@@ -3748,6 +3740,11 @@ const Parser = struct {
37483740 try p.warnExpected(.comma);
37493741 },
37503742 }
3743 if (p.eatToken(.r_paren)) |_| {
3744 return SmallSpan{ .zero_or_one = param_one };
3745 }
3746 const param = try p.expectParamDecl();
3747 if (param != 0) break param;
37513748 } else unreachable;
37523749
37533750 var list = std.ArrayList(Node.Index).init(p.gpa);
......@@ -3757,17 +3754,7 @@ const Parser = struct {
37573754
37583755 while (true) {
37593756 switch (p.token_tags[p.nextToken()]) {
3760 .comma => {
3761 if (p.token_tags[p.tok_i] == .r_paren) {
3762 p.tok_i += 1;
3763 return SmallSpan{ .multi = list.toOwnedSlice() };
3764 }
3765 const param = try p.expectParamDecl();
3766 if (param != 0) {
3767 try list.append(param);
3768 }
3769 continue;
3770 },
3757 .comma => {},
37713758 .r_paren => return SmallSpan{ .multi = list.toOwnedSlice() },
37723759 .colon, .r_brace, .r_bracket => {
37733760 p.tok_i -= 1;
......@@ -3780,6 +3767,11 @@ const Parser = struct {
37803767 try p.warnExpected(.comma);
37813768 },
37823769 }
3770 if (p.eatToken(.r_paren)) |_| {
3771 return SmallSpan{ .multi = list.toOwnedSlice() };
3772 }
3773 const param = try p.expectParamDecl();
3774 if (param != 0) try list.append(param);
37833775 }
37843776 }
37853777
lib/std/zig/parser_test.zig+12
......@@ -4549,6 +4549,18 @@ test "recovery: missing for payload" {
45494549 });
45504550}
45514551
4552test "recovery: missing comma in params" {
4553 try testError(
4554 \\fn foo(comptime bool what what) void { }
4555 \\fn bar(a: i32, b: i32 c) void { }
4556 \\
4557 , &[_]Error{
4558 .expected_token,
4559 .expected_token,
4560 .expected_token,
4561 });
4562}
4563
45524564const std = @import("std");
45534565const mem = std.mem;
45544566const warn = std.debug.warn;