summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-05-18 06:29:06 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-05-18 06:29:06 -0700
commit97fce155c0b92429b9deabfca31e35dbb5fe0d8f (patch)
tree08c0fada23ba0d93127e6dae0998f0a652963bdb
parent6ca427f995a76ed9c5bae2ab86f864ea5ae4d376 (diff)
downloadtxr-97fce155c0b92429b9deabfca31e35dbb5fe0d8f.tar.gz
txr-97fce155c0b92429b9deabfca31e35dbb5fe0d8f.tar.bz2
txr-97fce155c0b92429b9deabfca31e35dbb5fe0d8f.zip
Handle integer overflow in length_list.
* lib.c (length_list): Count using cnum only up to INT_PTR_MAX, then switch to bignums.
-rw-r--r--lib.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index 03409125..a0333930 100644
--- a/lib.c
+++ b/lib.c
@@ -2629,14 +2629,26 @@ val proper_list_p(val obj)
val length_list(val list)
{
cnum len = 0;
+ val bn_len;
gc_hint(list);
- while (consp(list)) {
+ while (consp(list) && len < INT_PTR_MAX) {
len++;
list = cdr(list);
}
- return num(len);
+
+ if (len < INT_PTR_MAX)
+ return num(len);
+
+ bn_len = num(INT_PTR_MAX);
+
+ while (consp(list)) {
+ bn_len = succ(bn_len);
+ list = cdr(list);
+ }
+
+ return bn_len;
}
val getplist(val list, val key)