authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-06 13:24:24+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:49:01+02:00
log910e3e51ba5e320a198ca5e9ca8584c94b735b04
treefb4b9d67f8cebc13864e60e2bbcf01d5395c8386
parent010a98dbfce6f42ae12fda09060e37748e58dc2d
signaturelock-open Commit is signed but in an unrecognized format.

parser: check field_state before further parsing

To prevent the fuzzer from being able to reach stack overflows, we need to give an error for invalid field/decl ordering before attempting to parse the next field.

1 files changed, 14 insertions(+), 14 deletions(-)

lib/std/zig/Parse.zig+14-14
...@@ -334,13 +334,6 @@ fn parseContainerMembers(p: *Parse) Error!Members {...@@ -334,13 +334,6 @@ fn parseContainerMembers(p: *Parse) Error!Members {
334 else => {334 else => {
335 const identifier = p.tok_i;335 const identifier = p.tok_i;
336 defer last_field = identifier;336 defer last_field = identifier;
337 const container_field = p.expectContainerField() catch |err| switch (err) {
338 error.OutOfMemory => |e| return e,
339 error.ParseError => {
340 p.findNextContainerMember();
341 continue;
342 },
343 };
344 switch (field_state) {337 switch (field_state) {
345 .none => field_state = .seen,338 .none => field_state = .seen,
346 .err, .seen => {},339 .err, .seen => {},
...@@ -363,6 +356,13 @@ fn parseContainerMembers(p: *Parse) Error!Members {...@@ -363,6 +356,13 @@ fn parseContainerMembers(p: *Parse) Error!Members {
363 field_state = .err;356 field_state = .err;
364 },357 },
365 }358 }
359 const container_field = p.expectContainerField() catch |err| switch (err) {
360 error.OutOfMemory => |e| return e,
361 error.ParseError => {
362 p.findNextContainerMember();
363 continue;
364 },
365 };
366 try p.scratch.append(p.gpa, container_field);366 try p.scratch.append(p.gpa, container_field);
367 switch (p.tokenTag(p.tok_i)) {367 switch (p.tokenTag(p.tok_i)) {
368 .comma => {368 .comma => {
...@@ -439,13 +439,6 @@ fn parseContainerMembers(p: *Parse) Error!Members {...@@ -439,13 +439,6 @@ fn parseContainerMembers(p: *Parse) Error!Members {
439439
440 const identifier = p.tok_i;440 const identifier = p.tok_i;
441 defer last_field = identifier;441 defer last_field = identifier;
442 const container_field = p.expectContainerField() catch |err| switch (err) {
443 error.OutOfMemory => |e| return e,
444 error.ParseError => {
445 p.findNextContainerMember();
446 continue;
447 },
448 };
449 switch (field_state) {442 switch (field_state) {
450 .none => field_state = .seen,443 .none => field_state = .seen,
451 .err, .seen => {},444 .err, .seen => {},
...@@ -468,6 +461,13 @@ fn parseContainerMembers(p: *Parse) Error!Members {...@@ -468,6 +461,13 @@ fn parseContainerMembers(p: *Parse) Error!Members {
468 field_state = .err;461 field_state = .err;
469 },462 },
470 }463 }
464 const container_field = p.expectContainerField() catch |err| switch (err) {
465 error.OutOfMemory => |e| return e,
466 error.ParseError => {
467 p.findNextContainerMember();
468 continue;
469 },
470 };
471 try p.scratch.append(p.gpa, container_field);471 try p.scratch.append(p.gpa, container_field);
472 switch (p.tokenTag(p.tok_i)) {472 switch (p.tokenTag(p.tok_i)) {
473 .comma => {473 .comma => {