Accessing &MORE arguments checks bounds.
authorStas Boukarev <stassats@gmail.com>
Thu, 14 Mar 2013 10:09:54 +0000 (14:09 +0400)
committerStas Boukarev <stassats@gmail.com>
Thu, 14 Mar 2013 10:09:54 +0000 (14:09 +0400)
(funcall (lambda (&rest args) (car args))) => garbage,
because &more accessing didn't check bounds.

Fixes lp#1154946.

NEWS
src/compiler/srctran.lisp
tests/dynamic-extent.impure.lisp

diff --git a/NEWS b/NEWS
index 5c6e598..848ea8a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ changes relative to sbcl-1.1.5:
   * bug fix: Better error messages for package operations (lp#1154776)
   * bug fix: delete-package on a nonexistent package should signal a cerror.
     (regression since 1.0.37.44).
+  * bug fix: accessing &MORE (stack allocated &REST) arguments checks bounds.
+    (lp#1154946)
 
 changes in sbcl-1.1.5 relative to sbcl-1.1.4:
   * minor incompatible change: SB-SPROF:WITH-PROFILING no longer loops
index 69c49af..ffeb6d6 100644 (file)
 
 (deftransform %rest-ref ((n list context count))
   (cond ((rest-var-more-context-ok list)
-         `(%more-arg context n))
+         `(and (< (the index n) count)
+               (%more-arg context n)))
         ((and (constant-lvar-p n) (zerop (lvar-value n)))
          `(car list))
         (t
index 6841e4d..3a227eb 100644 (file)
     (assert (every (lambda (x)
                      (sb-sys:sap= x (sb-sys:int-sap (+ 16 (ash 1 (1- width))))))
                    (funcall f (sb-sys:int-sap (ash 1 (1- width))))))))
+
+(with-test (:name :&more-bounds)
+  ;; lp#1154946
+  (assert (not (funcall (compile nil '(lambda (&rest args) (car args))))))
+  (assert (not (funcall (compile nil '(lambda (&rest args) (nth 6 args))))))
+  (assert (not (funcall (compile nil '(lambda (&rest args) (elt args 10))))))
+  (assert (not (funcall (compile nil '(lambda (&rest args) (cadr args))))))
+  (assert (not (funcall (compile nil '(lambda (&rest args) (third args)))))))