authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2024-06-23 21:37:11+09:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-03 02:53:37-04:00
log5e3bad3556435663fa9220390248a5ed4f75be47
treeabef508455b5ff10b5a25a72a9b8d97dc9e78f3d
parent1905137d0b692d19c511dab6c0f7e4dfad1808c1

Make 0e.0 and 0xp0 not crash

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,6 +8637,7 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token
8637 assert(bytes.len >= 2 and bytes[0] == '0' and bytes[1] == 'x'); // Validated by tokenizer8637 assert(bytes.len >= 2 and bytes[0] == '0' and bytes[1] == 'x'); // Validated by tokenizer
8638 return astgen.failOff(token, @intCast(i), "sign '{c}' cannot follow digit '{c}' in hex base", .{ bytes[i], bytes[i - 1] });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}
86428643
lib/std/zig/number_literal.zig+14
...@@ -56,6 +56,8 @@ pub const Error = union(enum) {...@@ -56,6 +56,8 @@ pub const Error = union(enum) {
56 invalid_character: usize,56 invalid_character: usize,
57 /// [+-] not immediately after [pPeE]57 /// [+-] not immediately after [pPeE]
58 invalid_exponent_sign: usize,58 invalid_exponent_sign: usize,
59 /// Period comes directly after exponent.
60 period_after_exponent: usize,
59};61};
6062
61/// Parse Zig number literal accepted by fmt.parseInt, fmt.parseFloat and big_int.setString.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,6 +110,9 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
108 continue;110 continue;
109 },111 },
110 'p', 'P' => if (base == 16) {112 'p', 'P' => if (base == 16) {
113 if (i == 2) {
114 return .{ .failure = .{ .digit_after_base = {} } };
115 }
111 float = true;116 float = true;
112 if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };117 if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };
113 if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };118 if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };
...@@ -116,6 +121,15 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {...@@ -116,6 +121,15 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
116 continue;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 float = true;133 float = true;
120 if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };134 if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
121 if (period) return .{ .failure = .duplicate_period };135 if (period) return .{ .failure = .duplicate_period };
test/cases/compile_errors/invalid_number_literals.zig created+29
...@@ -0,0 +1,29 @@
1comptime {
2 _ = 0e.0;
3}
4comptime {
5 _ = 0E.0;
6}
7comptime {
8 _ = 12e.0;
9}
10comptime {
11 _ = 12E.0;
12}
13comptime {
14 _ = 0xp0;
15}
16comptime {
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