wcc: reject final-band integer overflow; restore rewind columns

This commit is contained in:
2026-08-09 03:25:17 +09:00
parent cd11d6e573
commit 53a9e94736
5 changed files with 76 additions and 9 deletions

View File

@@ -181,6 +181,9 @@ static u64
parseint(const char *s, u64 n, int base, int *ok)
{
u64 v = 0;
u64 b = (u64)base;
u64 cutoff = (u64)~0ULL / b;
u64 cutlim = (u64)~0ULL % b;
int got = 0;
for (u64 i = 0; i < n; i++) {
int c = (unsigned char)s[i];
@@ -192,9 +195,11 @@ parseint(const char *s, u64 n, int base, int *ok)
else if (c >= 'A' && c <= 'F') d = c - 'A' + 10;
else { *ok = 0; return 0; }
if (d >= base) { *ok = 0; return 0; }
/* overflow? cheap check */
if (v > (u64)~0ULL / (u64)base) { *ok = 0; return 0; }
v = v * (u64)base + (u64)d;
if (v > cutoff || (v == cutoff && (u64)d > cutlim)) {
*ok = 0;
return 0;
}
v = v * b + (u64)d;
got = 1;
}
*ok = got;
@@ -369,6 +374,7 @@ lexnum(Lex *l, Pos start)
/* A typed suffix must be glued (no whitespace) to the digits. */
if (isidstart(lpeek(l, 0))) {
u64 sb = l->pos;
i32 sc = l->col;
while (isidcont(lpeek(l, 0))) lget(l);
u64 sl = l->pos - sb;
const char *names[] = {
@@ -387,9 +393,8 @@ lexnum(Lex *l, Pos start)
if (match) {
t.tsuffix = astrndup(l->a, l->src + sb, sl);
} else {
/* not a known suffix — rewind so the run becomes a
* separate token. */
l->pos = sb;
l->col = sc;
}
}
return t;