Commit 5e3bad3556

wooster0 <wooster0@proton.me>
2024-06-23 14:37:11
Make 0e.0 and 0xp0 not crash
This fixes those sequences of characters crashing.
1 parent 1905137
Changed files (3)
lib
test
cases
lib/std/zig/AstGen.zig
@@ -8637,6 +8637,7 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token
             assert(bytes.len >= 2 and bytes[0] == '0' and bytes[1] == 'x'); // Validated by tokenizer
             return astgen.failOff(token, @intCast(i), "sign '{c}' cannot follow digit '{c}' in hex base", .{ bytes[i], bytes[i - 1] });
         },
+        .period_after_exponent => |i| return astgen.failOff(token, @intCast(i), "unexpected period after exponent", .{}),
     }
 }
 
lib/std/zig/number_literal.zig
@@ -56,6 +56,8 @@ pub const Error = union(enum) {
     invalid_character: usize,
     /// [+-] not immediately after [pPeE]
     invalid_exponent_sign: usize,
+    /// Period comes directly after exponent.
+    period_after_exponent: usize,
 };
 
 /// Parse Zig number literal accepted by fmt.parseInt, fmt.parseFloat and big_int.setString.
@@ -108,6 +110,9 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
                 continue;
             },
             'p', 'P' => if (base == 16) {
+                if (i == 2) {
+                    return .{ .failure = .{ .digit_after_base = {} } };
+                }
                 float = true;
                 if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };
                 if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };
@@ -116,6 +121,15 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
                 continue;
             },
             '.' => {
+                if (exponent) {
+                    const digit_index = i - ".e".len;
+                    if (digit_index < bytes.len) {
+                        switch (bytes[digit_index]) {
+                            '0'...'9' => return .{ .failure = .{ .period_after_exponent = i } },
+                            else => {},
+                        }
+                    }
+                }
                 float = true;
                 if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
                 if (period) return .{ .failure = .duplicate_period };
test/cases/compile_errors/invalid_number_literals.zig
@@ -0,0 +1,29 @@
+comptime {
+    _ = 0e.0;
+}
+comptime {
+    _ = 0E.0;
+}
+comptime {
+    _ = 12e.0;
+}
+comptime {
+    _ = 12E.0;
+}
+comptime {
+    _ = 0xp0;
+}
+comptime {
+    _ = 0xP0;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:11: error: unexpected period after exponent
+// :5:11: error: unexpected period after exponent
+// :8:12: error: unexpected period after exponent
+// :11:12: error: unexpected period after exponent
+// :14:9: error: expected a digit after base prefix
+// :17:9: error: expected a digit after base prefix