aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2020-12-27 09:22:02 +0100
committerLars Ingebrigtsen2020-12-27 09:22:02 +0100
commiteb98afaf354288c583ceb2fbdd647841d5c76b2d (patch)
tree8b6b57a97af020820841cb3f86de350368d194ce
parent80420faf4921ffe5e9d4c4f9595941acf3156e50 (diff)
downloademacs-eb98afaf354288c583ceb2fbdd647841d5c76b2d.tar.gz
emacs-eb98afaf354288c583ceb2fbdd647841d5c76b2d.zip
Fix up length_internal with degenerate length inputs
* src/fns.c (length_internal): Protect against edge conditions.
-rw-r--r--src/fns.c7
-rw-r--r--test/src/fns-tests.el11
2 files changed, 16 insertions, 2 deletions
diff --git a/src/fns.c b/src/fns.c
index 0fded92aeb2..6aad119d1f9 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -159,14 +159,14 @@ EMACS_INT length_internal (Lisp_Object sequence, int len)
159 if (len < 0xffff) 159 if (len < 0xffff)
160 while (CONSP (sequence)) 160 while (CONSP (sequence))
161 { 161 {
162 if (--len == 0) 162 if (--len <= 0)
163 return -1; 163 return -1;
164 sequence = XCDR (sequence); 164 sequence = XCDR (sequence);
165 } 165 }
166 /* Signal an error on circular lists. */ 166 /* Signal an error on circular lists. */
167 else 167 else
168 FOR_EACH_TAIL (sequence) 168 FOR_EACH_TAIL (sequence)
169 if (--len == 0) 169 if (--len <= 0)
170 return -1; 170 return -1;
171 return len; 171 return len;
172} 172}
@@ -210,6 +210,9 @@ counted. */)
210 CHECK_FIXNUM (length); 210 CHECK_FIXNUM (length);
211 EMACS_INT len = XFIXNUM (length); 211 EMACS_INT len = XFIXNUM (length);
212 212
213 if (len < 0)
214 return Qnil;
215
213 if (CONSP (sequence)) 216 if (CONSP (sequence))
214 return length_internal (sequence, len + 1) == 1? Qt: Qnil; 217 return length_internal (sequence, len + 1) == 1? Qt: Qnil;
215 else 218 else
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index 3486c745bf3..e66dad44a1a 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -1025,6 +1025,17 @@
1025 (should (length= "abc" 3)) 1025 (should (length= "abc" 3))
1026 (should-not (length= "abc" 4)) 1026 (should-not (length= "abc" 4))
1027 1027
1028 (should-not (length< (list 1 2 3) -1))
1029 (should-not (length< (list 1 2 3) 0))
1030 (should-not (length< (list 1 2 3) -10))
1031
1032 (should (length> (list 1 2 3) -1))
1033 (should (length> (list 1 2 3) 0))
1034
1035 (should-not (length= (list 1 2 3) -1))
1036 (should-not (length= (list 1 2 3) 0))
1037 (should-not (length= (list 1 2 3) 1))
1038
1028 (should-error 1039 (should-error
1029 (let ((list (list 1))) 1040 (let ((list (list 1)))
1030 (setcdr list list) 1041 (setcdr list list)