shithub: femtolisp

Download patch

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);
 
 /*