commit 37bec9536e154779f844ec17e6f069bdbd857b22
parent 39b03bce994aac936c2ce7eb7b7665e6f5f38d9b
Author: Bor Grošelj Simić <bgs@turminal.net>
Date: Tue, 7 Feb 2023 23:13:16 +0100
hare::lex: error out on overflowing integer exponents
References: https://todo.sr.ht/~sircmpwn/hare/737
Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
Diffstat:
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha
@@ -14,6 +14,7 @@ use sort;
use strconv;
use strings;
use strio;
+use types;
export type lexer = struct {
in: io::handle,
@@ -563,21 +564,21 @@ fn lex_literal(lex: *lexer) (token | error) = {
case void =>
yield "";
};
- let suff = if (suff == "u8") ltok::LIT_U8
- else if (suff == "u16") ltok::LIT_U16
- else if (suff == "u32") ltok::LIT_U32
- else if (suff == "u64") ltok::LIT_U64
- else if (suff == "u") ltok::LIT_UINT
- else if (suff == "z") ltok::LIT_SIZE
- else if (suff == "i8") ltok::LIT_I8
- else if (suff == "i16") ltok::LIT_I16
- else if (suff == "i32") ltok::LIT_I32
- else if (suff == "i64") ltok::LIT_I64
- else if (suff == "i") ltok::LIT_INT
- else if (suff == "" && !float && exp >= 0) ltok::LIT_ICONST
- else if (suff == "f32") ltok::LIT_F32
- else if (suff == "f64") ltok::LIT_F64
- else if (suff == "" && (float || exp < 0)) ltok::LIT_FCONST
+ let (suff, signed) = if (suff == "u8") (ltok::LIT_U8, false)
+ else if (suff == "u16") (ltok::LIT_U16, false)
+ else if (suff == "u32") (ltok::LIT_U32, false)
+ else if (suff == "u64") (ltok::LIT_U64, false)
+ else if (suff == "u") (ltok::LIT_UINT, false)
+ else if (suff == "z") (ltok::LIT_SIZE, false)
+ else if (suff == "i8") (ltok::LIT_I8, true)
+ else if (suff == "i16") (ltok::LIT_I16, true)
+ else if (suff == "i32") (ltok::LIT_I32, true)
+ else if (suff == "i64") (ltok::LIT_I64, true)
+ else if (suff == "i") (ltok::LIT_INT, true)
+ else if (suff == "" && !float && exp >= 0) (ltok::LIT_ICONST, false)
+ else if (suff == "f32") (ltok::LIT_F32, false)
+ else if (suff == "f64") (ltok::LIT_F64, false)
+ else if (suff == "" && (float || exp < 0)) (ltok::LIT_FCONST, false)
else return syntaxerr(loc, "invalid literal suffix");
let exp = if (exp < 0) switch (suff) {
@@ -598,7 +599,14 @@ fn lex_literal(lex: *lexer) (token | error) = {
let val = match (val) {
case let val: u64 =>
for (let i = 0z; i < exp; i += 1) {
+ let old = val;
val *= 10;
+ if (val / 10 != old) {
+ return syntaxerr(loc, "overflow in exponent");
+ };
+ };
+ if (signed && val > types::I64_MIN: u64) {
+ return syntaxerr(loc, "overflow in exponent");
};
yield val;
case let val: f64 =>
diff --git a/hare/parse/+test/loc.ha b/hare/parse/+test/loc.ha
@@ -52,7 +52,7 @@ fn expr_testloc(srcs: str...) void = for (let i = 0z; i < len(srcs); i += 1) {
expr_testloc("(foo, bar)");
expr_testloc("null", "void", "true", `"שלום"`, "'a'");
expr_testloc("[foo, bar]");
- expr_testloc("123", "-123.456", "123z", "123e+456");
+ expr_testloc("123", "-123.456", "123z", "123e+3");
expr_testloc("continue", "continue :foo");
expr_testloc("defer foo");
expr_testloc("delete(foo[bar])", "delete(foo[bar..baz])");