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

parser: warn on non-final varargs before further parsing

To prevent the fuzzer from being able to reach stack overflows, we need to give an error for non-final varargs (...) before parsing the next argument.

1 files changed, 6 insertions(+), 5 deletions(-)

lib/std/zig/Parse.zig+6-5
......@@ -3371,6 +3371,7 @@ fn expectContainerDeclAuto(p: *Parse) !Node.Index {
33713371/// Give a helpful error message for those transitioning from
33723372/// C's 'struct Foo {};' to Zig's 'const Foo = struct {};'.
33733373fn parseCStyleContainer(p: *Parse) Error!bool {
3374 if (!p.recover) return false;
33743375 const main_token = p.tok_i;
33753376 switch (p.tokenTag(p.tok_i)) {
33763377 .keyword_enum, .keyword_union, .keyword_struct => {},
......@@ -3436,10 +3437,13 @@ fn parseParamDeclList(p: *Parse) !SmallSpan {
34363437 _ = try p.expectToken(.l_paren);
34373438 const scratch_top = p.scratch.items.len;
34383439 defer p.scratch.shrinkRetainingCapacity(scratch_top);
3439 var varargs: union(enum) { none, seen, nonfinal: TokenIndex } = .none;
3440 var varargs: enum { none, seen, err } = .none;
34403441 while (true) {
34413442 if (p.eatToken(.r_paren)) |_| break;
3442 if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i };
3443 if (varargs == .seen) {
3444 try p.warnMsg(.{ .tag = .varargs_nonfinal, .token = p.tok_i });
3445 varargs = .err;
3446 }
34433447 const opt_param = try p.expectParamDecl();
34443448 if (opt_param) |param| {
34453449 try p.scratch.append(p.gpa, param);
......@@ -3457,9 +3461,6 @@ fn parseParamDeclList(p: *Parse) !SmallSpan {
34573461 else => try p.warn(.expected_comma_after_param),
34583462 }
34593463 }
3460 if (varargs == .nonfinal) {
3461 try p.warnMsg(.{ .tag = .varargs_nonfinal, .token = varargs.nonfinal });
3462 }
34633464 const params = p.scratch.items[scratch_top..];
34643465 return switch (params.len) {
34653466 0 => .{ .zero_or_one = .none },