ref: 98726d68b76ebcb668a38fe21a2caa9e929e0525
parent: 64785f014f9260768224d218899905d1ec19d269
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Nov 10 18:44:58 EST 2024
fix UBs found while running tests; fix negation for uint64 underflowing
--- a/3rd/mp/mplogic.c
+++ b/3rd/mp/mplogic.c
@@ -16,7 +16,7 @@
*/
static void
-mplogic(mpint *b1, mpint *b2, mpint *sum, int fl)
+mplogic(mpint *b1, mpint *b2, mpint *sum, uint32_t fl)
{
mpint *t;
mpdigit *dp1, *dp2, *dpo, d1, d2, d;
--- a/3rd/mp/strtomp.c
+++ b/3rd/mp/strtomp.c
@@ -5,7 +5,7 @@
{
char *p, *next;
mpdigit x;
- int i;
+ uint32_t i;
i = 1<<s;
for(p = a; (dec16chr(*p) & 255) < i; p++)
--- a/3rd/mp/u16.c
+++ b/3rd/mp/u16.c
@@ -12,7 +12,7 @@
return c;
}
-int
+uint32_t
dec16chr(int c)
{
int o;
--- a/cvalues.c
+++ b/cvalues.c
@@ -1002,7 +1002,7 @@
case T_UINT32: Uaccum += *(uint32_t*)a; break;
case T_INT64:
i64 = *(int64_t*)a;
- if(i64 > 0){
+ if(i64 >= 0){
if(addof_uint64(Uresult, Uaccum, (uint64_t)i64)){
if(Maccum == nil)
Maccum = mpnew(0);
@@ -1015,7 +1015,8 @@
if(subof_int64(Sresult, Saccum, i64)){
if(Maccum == nil)
Maccum = mpnew(0);
- x = vtomp(i64, nil);
+ x = uvtomp(-(uint64_t)i64, nil);
+ x->sign = -1;
mpadd(Maccum, x, Maccum);
mpfree(x);
}else{
@@ -1070,7 +1071,7 @@
return mk_mpint(Maccum);
}
if(Saccum < 0){
- uint64_t negpart = (uint64_t)(-Saccum);
+ uint64_t negpart = -(uint64_t)Saccum;
if(negpart > Uaccum){
Saccum += (int64_t)Uaccum;
// return value in Saccum
@@ -1102,9 +1103,10 @@
value_t
fl_neg(value_t n)
{
- uint32_t ui32;
int32_t i32;
int64_t i64;
+ uint32_t ui32;
+ uint64_t ui64;
mpint *mp;
numerictype_t pt;
fixnum_t pi;
@@ -1130,8 +1132,8 @@
return mk_int32(-i32);
case T_UINT32:
ui32 = *(uint32_t*)a;
- if(ui32 <= ((uint32_t)INT32_MAX)+1)
- return mk_int32(-(int32_t)ui32);
+ if(ui32 <= (uint32_t)INT32_MAX+1)
+ return mk_int32(-(uint32_t)ui32);
return mk_int64(-(int64_t)ui32);
case T_INT64:
i64 = *(int64_t*)a;
@@ -1138,7 +1140,13 @@
if(i64 == (int64_t)BIT63)
return mk_uint64((uint64_t)BIT63);
return mk_int64(-i64);
- case T_UINT64: return mk_int64(-(int64_t)*(uint64_t*)a);
+ case T_UINT64:
+ ui64 = *(uint64_t*)a;
+ if(ui64 <= (uint64_t)INT64_MAX+1)
+ return mk_int64(-(uint64_t)ui64);
+ mp = uvtomp(ui64, nil);
+ mp->sign = -1;
+ return mk_mpint(mp);
case T_MPINT:
mp = mpcopy(*(mpint**)a);
mpsub(mpzero, mp, mp);
--- a/posix/mp.h
+++ b/posix/mp.h
@@ -52,7 +52,7 @@
extern int enc64chr(int);
extern int dec32chr(int);
extern int enc32chr(int);
-extern int dec16chr(int);
+extern uint32_t dec16chr(int);
extern int enc16chr(int);
/*