Re: lisp function questions
- From: "josephoswaldgg@xxxxxxxxxxx" <josephoswald@xxxxxxxxx>
- Date: 30 Sep 2005 09:19:01 -0700
Jon Harrop wrote:
>
> 2. I came up with this hideous concoction:
>
> * (defun average (list) (/ (eval (cons '+ list)) (length list)))
>
> AVERAGE
> * (average '(1 2 3 4))
>
> 5/2
Finally, to elaborate on Pascal's point on security, which you probably
missed because you are doing all these things from the read-eval-print
loop, here's a more explicit demonstration of the security pitfalls of
using eval on general lists.
;;; bad-eval.lisp
;;;
;;;
(defun bad-average (list)
(/ (eval (cons '+ list)) (length list)))
(defun better-average (list)
(/ (apply #'+ list) (length list)))
(defun get-number-list (input-stream)
"Quick demo of getting a Lisp list from unreliable source."
(format t "Welcome to my web site.~%Enter numbers, type :DONE when
done~%")
(let ((*read-eval* nil)) ; protect against #. at least
(do (num
(list nil (cons num list)))
((eql num :DONE) (progn (format t "Thank you!!~%")
(nreverse (cdr list))))
; discard DONE, put back in order
(format t "Enter number: ")
(setf num (read input-stream)))))
;; SHOULD NOT USE READ in general
(defun test-bad-eval (string)
(let ((num-list (get-number-list (make-string-input-stream string))))
(progn
(format t "Testing better average: ")
(format t "~A~%"
(ignore-errors (better-average num-list)))
;; make at least one thing robust...
(format t "Testing bad average:")
(format t "~A~%"
(ignore-errors (bad-average num-list))))))
;;;; verification
(test-bad-eval "1
2
3
:DONE
")
(test-bad-eval "1
2
(progn (format t \"~%GOTCHA~%\") 3)
:DONE
")
.
- References:
- lisp function questions
- From: dan655t
- Re: lisp function questions
- From: Pascal Bourguignon
- Re: lisp function questions
- From: dan655t
- lisp function questions
- Prev by Date: macro question
- Next by Date: Re: Beginner - Function Critique
- Previous by thread: Re: lisp function questions
- Next by thread: Re: lisp function questions
- Index(es):