Commit 4aa8462cc9

travisstaloch <twostepted@gmail.com>
2022-12-20 16:33:40
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()
1 parent 3a1295c
Changed files (2)
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 => {},
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 {