From 4aa8462cc936820bc2c81ea1f3cfc613ff07a9f7 Mon Sep 17 00:00:00 2001 From: travisstaloch Date: Tue, 20 Dec 2022 07:33:40 -0800 Subject: [PATCH] std.zig: fix integer overflows during parsing these were found while fuzzing zls. this patch prevents overflow for the following file contents and adds tests for them. * `enum(u32)` - causes overflow in std.zig.Ast.fullContainerDecl() * `*x` - causes overflow in std.zig.Ast.fullPtrType() * `**x` - causes overflow in std.zig.Ast.firstToken() --- lib/std/zig/Ast.zig | 9 ++++++--- lib/std/zig/parser_test.zig | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index 43cda7a977..c2439437e7 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -634,8 +634,8 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { return switch (token_tags[main_token]) { .asterisk, .asterisk_asterisk, - => switch (token_tags[main_token - 1]) { - .l_bracket => main_token - 1, + => switch (token_tags[main_token -| 1]) { + .l_bracket => main_token -| 1, else => main_token, }, .l_bracket => main_token, @@ -2015,7 +2015,7 @@ fn fullPtrType(tree: Ast, info: full.PtrType.Components) full.PtrType { .asterisk_asterisk, => switch (token_tags[info.main_token + 1]) { .r_bracket, .colon => .Many, - .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One, + .identifier => if (token_tags[info.main_token -| 1] == .l_bracket) Size.C else .One, else => .One, }, .l_bracket => Size.Slice, @@ -2060,6 +2060,9 @@ fn fullContainerDecl(tree: Ast, info: full.ContainerDecl.Components) full.Contai .ast = info, .layout_token = null, }; + + if (info.main_token == 0) return result; + switch (token_tags[info.main_token - 1]) { .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1, else => {}, diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index e2f31b6072..e65a9fcaac 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -221,6 +221,27 @@ test "zig fmt: top-level tuple function call type" { ); } +test "zig fmt: top-level enum missing 'const name ='" { + try testError( + \\enum(u32) + \\ + , &[_]Error{.expected_token}); +} + +test "zig fmt: top-level bare asterisk+identifier" { + try testCanonical( + \\*x + \\ + ); +} + +test "zig fmt: top-level bare asterisk+asterisk+identifier" { + try testCanonical( + \\**x + \\ + ); +} + test "zig fmt: C style containers" { try testError( \\struct Foo {