From fa2e7181b3f21505a340ae25a5f41998f67665a8 Mon Sep 17 00:00:00 2001 From: Stas Boukarev Date: Thu, 14 Mar 2013 14:09:54 +0400 Subject: [PATCH] Accessing &MORE arguments checks bounds. (funcall (lambda (&rest args) (car args))) => garbage, because &more accessing didn't check bounds. Fixes lp#1154946. --- NEWS | 2 ++ src/compiler/srctran.lisp | 3 ++- tests/dynamic-extent.impure.lisp | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5c6e598..848ea8a 100644 --- 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 diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp index 69c49af..ffeb6d6 100644 --- a/src/compiler/srctran.lisp +++ b/src/compiler/srctran.lisp @@ -4195,7 +4195,8 @@ (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 diff --git a/tests/dynamic-extent.impure.lisp b/tests/dynamic-extent.impure.lisp index 6841e4d..3a227eb 100644 --- a/tests/dynamic-extent.impure.lisp +++ b/tests/dynamic-extent.impure.lisp @@ -1098,3 +1098,11 @@ (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))))))) -- 1.7.10.4