| author | |
| committer | |
| log | 5e3bad3556435663fa9220390248a5ed4f75be47 |
| tree | abef508455b5ff10b5a25a72a9b8d97dc9e78f3d |
| parent | 1905137d0b692d19c511dab6c0f7e4dfad1808c1 |
This fixes those sequences of characters crashing.3 files changed, 44 insertions(+), 0 deletions(-)
lib/std/zig/AstGen.zig+1| ... | ... | @@ -8637,6 +8637,7 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token |
| 8637 | 8637 | assert(bytes.len >= 2 and bytes[0] == '0' and bytes[1] == 'x'); // Validated by tokenizer |
| 8638 | 8638 | return astgen.failOff(token, @intCast(i), "sign '{c}' cannot follow digit '{c}' in hex base", .{ bytes[i], bytes[i - 1] }); |
| 8639 | 8639 | }, |
| 8640 | .period_after_exponent => |i| return astgen.failOff(token, @intCast(i), "unexpected period after exponent", .{}), | |
| 8640 | 8641 | } |
| 8641 | 8642 | } |
| 8642 | 8643 |
lib/std/zig/number_literal.zig+14| ... | ... | @@ -56,6 +56,8 @@ pub const Error = union(enum) { |
| 56 | 56 | invalid_character: usize, |
| 57 | 57 | /// [+-] not immediately after [pPeE] |
| 58 | 58 | invalid_exponent_sign: usize, |
| 59 | /// Period comes directly after exponent. | |
| 60 | period_after_exponent: usize, | |
| 59 | 61 | }; |
| 60 | 62 | |
| 61 | 63 | /// 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 { |
| 108 | 110 | continue; |
| 109 | 111 | }, |
| 110 | 112 | 'p', 'P' => if (base == 16) { |
| 113 | if (i == 2) { | |
| 114 | return .{ .failure = .{ .digit_after_base = {} } }; | |
| 115 | } | |
| 111 | 116 | float = true; |
| 112 | 117 | if (exponent) return .{ .failure = .{ .duplicate_exponent = i } }; |
| 113 | 118 | if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } }; |
| ... | ... | @@ -116,6 +121,15 @@ pub fn parseNumberLiteral(bytes: []const u8) Result { |
| 116 | 121 | continue; |
| 117 | 122 | }, |
| 118 | 123 | '.' => { |
| 124 | if (exponent) { | |
| 125 | const digit_index = i - ".e".len; | |
| 126 | if (digit_index < bytes.len) { | |
| 127 | switch (bytes[digit_index]) { | |
| 128 | '0'...'9' => return .{ .failure = .{ .period_after_exponent = i } }, | |
| 129 | else => {}, | |
| 130 | } | |
| 131 | } | |
| 132 | } | |
| 119 | 133 | float = true; |
| 120 | 134 | if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } }; |
| 121 | 135 | if (period) return .{ .failure = .duplicate_period }; |
test/cases/compile_errors/invalid_number_literals.zig created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | comptime { | |
| 2 | _ = 0e.0; | |
| 3 | } | |
| 4 | comptime { | |
| 5 | _ = 0E.0; | |
| 6 | } | |
| 7 | comptime { | |
| 8 | _ = 12e.0; | |
| 9 | } | |
| 10 | comptime { | |
| 11 | _ = 12E.0; | |
| 12 | } | |
| 13 | comptime { | |
| 14 | _ = 0xp0; | |
| 15 | } | |
| 16 | comptime { | |
| 17 | _ = 0xP0; | |
| 18 | } | |
| 19 | ||
| 20 | // error | |
| 21 | // backend=stage2 | |
| 22 | // target=native | |
| 23 | // | |
| 24 | // :2:11: error: unexpected period after exponent | |
| 25 | // :5:11: error: unexpected period after exponent | |
| 26 | // :8:12: error: unexpected period after exponent | |
| 27 | // :11:12: error: unexpected period after exponent | |
| 28 | // :14:9: error: expected a digit after base prefix | |
| 29 | // :17:9: error: expected a digit after base prefix |