From 3f5f9bcaf01c0f6b3382f6fb85daa3ac7857ebee Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sun, 16 Aug 2020 02:48:41 +0200 Subject: [PATCH] Fix numeric constant overflow checks --- src/asm/lexer.c | 17 ++++++++++------- test/asm/equs-nest.out | 1 + test/asm/line-continuation-whitespace.asm | 1 - test/asm/local-purge.out | 2 +- test/asm/overflow.err | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index d2e4970a..12f9ea1a 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -920,7 +920,7 @@ static void readNumber(int radix, int32_t baseValue) if (c < '0' || c > '0' + radix - 1) break; - if (value > UINT32_MAX / radix) + if (value > (UINT32_MAX - (c - '0')) / radix) warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); value = value * radix + (c - '0'); @@ -940,7 +940,7 @@ static void readFractionalPart(void) if (c < '0' || c > '9') break; - if (divisor > UINT32_MAX / 10) { + if (divisor > (UINT32_MAX - (c - '0')) / 10) { warning(WARNING_LARGE_CONSTANT, "Precision of fixed-point constant is too large\n"); /* Discard any additional digits */ @@ -948,6 +948,7 @@ static void readFractionalPart(void) shiftChars(1); break; } + value = value * 10 + (c - '0'); } if (yylval.nConstValue > INT16_MAX || yylval.nConstValue < INT16_MIN) @@ -972,6 +973,8 @@ static void readBinaryNumber(void) /* TODO: handle `-b`'s dynamic chars */ if (c != '0' && c != '1') break; + if (value > (UINT32_MAX - (c - '0')) / 2) + warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); value = value * 2 + (c - '0'); shiftChars(1); @@ -998,7 +1001,7 @@ static void readHexNumber(void) else break; - if (value > UINT32_MAX / 16) + if (value > (UINT32_MAX - c) / 16) warning(WARNING_LARGE_CONSTANT, "Integer constant is too large\n"); value = value * 16 + c; @@ -1030,16 +1033,16 @@ static void readGfxConstant(void) bp0 = bp0 << 1 | (pixel & 1); bp1 = bp1 << 1 | (pixel >> 1); } - if (width <= 8) + if (width < 9) width++; shiftChars(1); } if (width == 0) - error("Invalid gfx constant, no digits after '`'\n"); - else if (width == 8) + error("Invalid graphics constant, no digits after '`'\n"); + else if (width == 9) warning(WARNING_LARGE_CONSTANT, - "Gfx constant is too large, only 8 first pixels considered\n"); + "Graphics constant is too long, only 8 first pixels considered\n"); yylval.nConstValue = bp1 << 8 | bp0; } diff --git a/test/asm/equs-nest.out b/test/asm/equs-nest.out index e69de29b..f985b46a 100644 --- a/test/asm/equs-nest.out +++ b/test/asm/equs-nest.out @@ -0,0 +1 @@ +Success! diff --git a/test/asm/line-continuation-whitespace.asm b/test/asm/line-continuation-whitespace.asm index 52b6b465..404e536a 100644 --- a/test/asm/line-continuation-whitespace.asm +++ b/test/asm/line-continuation-whitespace.asm @@ -2,7 +2,6 @@ ; file doesn't cause a segfault. bar: MACRO - WARN "" ENDM foo: bar baz\ diff --git a/test/asm/local-purge.out b/test/asm/local-purge.out index ebfabbe4..8b137891 100644 --- a/test/asm/local-purge.out +++ b/test/asm/local-purge.out @@ -1 +1 @@ -$0 + diff --git a/test/asm/overflow.err b/test/asm/overflow.err index b51baa5e..a3b44942 100644 --- a/test/asm/overflow.err +++ b/test/asm/overflow.err @@ -3,6 +3,6 @@ warning: overflow.asm(24): [-Wdiv] warning: overflow.asm(25): [-Wdiv] Division of -2147483648 by -1 yields -2147483648 warning: overflow.asm(39): [-Wlarge-constant] - Integer constant '4294967296' is too large + Integer constant is too large warning: overflow.asm(42): [-Wlarge-constant] - Graphics constant '`333333333' is too long + Graphics constant is too long, only 8 first pixels considered