shithub: sl

Download patch

ref: 6990fde0694af3d4343ce177e63632f391059493
parent: d1d2656950c6f97c6d728ea242ec6e6703ecf45a
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Apr 23 20:52:16 EDT 2025

aref/aset/tosize: ensure the index is non-zero; use usize for indexing

--- a/src/cvalues.c
+++ b/src/cvalues.c
@@ -399,17 +399,25 @@
 usize
 tosize(sl_v n)
 {
-	if(isfixnum(n))
-		return numval(n);
-	if(isubnum(n))
-		return ubnumval(n);
 	if(iscvalue(n)){
-		sl_cv *cv = ptr(n);
-		if(sizeof(usize) > 4)
-			return conv_to_u64(n, cv_data(cv), cv_numtype(cv));
-		return conv_to_u32(n, cv_data(cv), cv_numtype(cv));
+		if(numeric_compare(n, fixnum(0), false, false, true) >= 0){
+			sl_cv *cv = ptr(n);
+			if(sizeof(usize) > 4)
+				return conv_to_u64(n, cv_data(cv), cv_numtype(cv));
+			return conv_to_u32(n, cv_data(cv), cv_numtype(cv));
+		}
+	}else{
+		sl_fx x;
+		if(isfixnum(n))
+			x = numval(n);
+		else if(isubnum(n))
+			x = ubnumval(n);
+		else
+			cthrow(type_error(nil, "num", n), n);
+		if(x >= 0)
+			return x;
 	}
-	cthrow(type_error(nil, "num", n), n);
+	cthrow(lerrorf(sl_errarg, "tosize: negative value"), n);
 }
 
 soffset
@@ -820,14 +828,14 @@
 }
 
 static void
-check_addr_args(sl_v arr, sl_v ind, u8int **data, int *index)
+check_addr_args(sl_v arr, sl_v ind, u8int **data, usize *index)
 {
-	int numel;
+	usize numel;
 	sl_cv *cv = ptr(arr);
 	*data = cv_data(cv);
 	numel = cv_len(cv)/cv_class(cv)->elsz;
 	*index = tosize(ind);
-	if(*index < 0 || *index >= numel)
+	if(*index >= numel)
 		cthrow(bounds_error(arr, ind), arr);
 }
 
@@ -835,7 +843,7 @@
 cvalue_arr_aref(sl_v *args)
 {
 	u8int *data;
-	int index;
+	usize index;
 	check_addr_args(args[0], args[1], &data, &index);
 
 	sl_type *eltype = cv_class(ptr(args[0]))->eltype;
@@ -867,7 +875,8 @@
 sl_v
 cvalue_arr_aset(sl_v *args)
 {
-	u8int *data; int index;
+	u8int *data;
+	usize index;
 	sl_type *eltype = cv_class(ptr(args[0]))->eltype;
 	check_addr_args(args[0], args[1], &data, &index);
 	u8int *dest = data + index*eltype->size;