shithub: femtolisp

Download patch

ref: 3c5b2aa9bb8dd8d34e9cce4006d31ae81cfe9d2c
parent: 67e32a1c1140da65b2923b20a5387e853c5bf8c2
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Jan 2 14:53:21 EST 2025

libmp: fix UBs

--- a/3rd/mp/mpdiv.c
+++ b/3rd/mp/mpdiv.c
@@ -30,8 +30,10 @@
 			for(s = 0; ((divisor->p[0] >> s) & 1) == 0; s++)
 				;
 			mpright(dividend, s, quotient);
-			if(sign < 0)
-				quotient->sign ^= (-mpmagcmp(quotient, mpzero) >> 31) << 1;
+			if(sign < 0){
+				int xxx = mpmagcmp(quotient, mpzero) > 0 ? -2 : 0;
+				quotient->sign ^= xxx;
+			}
 		}
 		if(remainder != nil){
 			remainder->flags |= dividend->flags & MPtimesafe;
--- a/3rd/mp/mpfmt.c
+++ b/3rd/mp/mpfmt.c
@@ -115,7 +115,10 @@
 			else if(x != 0)
 				return -1;
 			*out = '0' + (x & 7);
-			x = y >> (Dbits-i);
+			if((Dbits-i) >= 64)
+				x = 0;
+			else
+				x = y >> (Dbits-i);
 		}
 	}
 	if(i > 0)
--- a/3rd/mp/mplogic.c
+++ b/3rd/mp/mplogic.c
@@ -103,7 +103,7 @@
 		b2 = t;
 	}
 	fl = (b1->sign & 10) ^ (b2->sign & 12);
-	sum->sign = (int)(fl << 28) >> 31 | 1;
+	sum->sign = (int)((uint32_t)fl << 28) >> 31 | 1;
 	mpbits(sum, b1->top*Dbits+1);
 	dp1 = b1->p;
 	dp2 = b2->p;
--- a/3rd/mp/strtomp.c
+++ b/3rd/mp/strtomp.c
@@ -51,7 +51,10 @@
 Digout:
 			i -= Dbits;
 			b->p[b->top++] = x;
-			x = y >> (3-i);
+			if(i <= -(64-3))
+				x = 0;
+			else
+				x = y >> (3-i);
 		}
 	}
 	if(i > 0)
--- a/3rd/mp/test/convtest.c
+++ b/3rd/mp/test/convtest.c
@@ -52,8 +52,9 @@
 		mag = i % 128; \
 		itomp(sign, r); \
 		mpleft(r, mag, r);
+
 #define XTOMP_END(_func,_type,_format)  \
-		_func(sign * ((_type)1<<mag), m); \
+		_func(sign * (_type)(1ULL<<mag), m); \
 		if(mpcmp(r, m) != 0){ \
 			fprintf(stderr, "FAIL: "#_func"("_format"): return value: got %s, expected %s\n", sign * ((_type)1<<mag), MFMT(m), MFMT(r)); \
 			fail=1; \
@@ -76,7 +77,7 @@
 
 MPTOX(test_mptoui, uint32_t, mptoui)
 	if(mag < 32 && sign > 0)
-		e = 1<<mag;
+		e = 1U<<mag;
 	else
 		e = sign > 0 ? -1 : 0;
 MPTOX_END(mptoui, "%#x")
@@ -91,7 +92,7 @@
 
 MPTOX(test_mptouv, uint64_t, mptouv)
 	if(mag < 64 && sign > 0)
-		e = 1LL<<mag;
+		e = 1ULL<<mag;
 	else
 		e = sign > 0 ? -1ULL : 0;
 MPTOX_END(mptouv, "%#"PRIx64)