How do you securely parse untrusted input in Common Lisp? Given that there is no parse-float etc, and that read-from-string will execute reader macros like #. (read time eval).
e.g. (read-from-string "#.(+ 1 2)") => 3
How do you securely parse untrusted input in Common Lisp? Given that there is no parse-float etc, and that read-from-string will execute reader macros like #. (read time eval).
e.g. (read-from-string "#.(+ 1 2)") => 3
Generally, just that the standard code reader is so readily available and can read many kinds of input does not mean that you should use it to read anything but code.
There are many libraries for parsing a lot of things, e. g. parse-number
for the Lisp number formats, fare-csv
for CSV files (among many other CSV libraries), json-streams
for JSON (again, many others). For most formats, you can just do a system-apropos
lookup with Quicklisp.
I can't find the other question or comment that described some of the safe input handling procedures for Common Lisp (if someone else finds them, please post a comment!), but there are at least two important things that you might do:
(let ((*readtable* (copy-readtable)))
(set-macro-character #\n (constantly 'injected))
(read-from-string "(#.(+ 2 5) n)"))
;;=> (7 INJECTED)
(let ((*readtable* (copy-readtable)))
(set-macro-character #\n (constantly 'injected))
(with-standard-io-syntax
(let ((*read-eval* nil))
(read-from-string "(#.(+ 2 5) n)"))))
;; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR
;; "can't read #. while *READ-EVAL* is NIL" {1004DA3603}>.
(let ((*readtable* (copy-readtable)))
(set-macro-character #\n (constantly 'injected))
(list (read-from-string "(n)")
(with-standard-io-syntax
(let ((*read-eval* nil))
(read-from-string "(n)")))))
;; ((INJECTED) (N))
*read-eval*
to NIL
inside with-standard-io-syntax
, because the latter will bind it to its default value T
!!! –
Cobbs Generally, just that the standard code reader is so readily available and can read many kinds of input does not mean that you should use it to read anything but code.
There are many libraries for parsing a lot of things, e. g. parse-number
for the Lisp number formats, fare-csv
for CSV files (among many other CSV libraries), json-streams
for JSON (again, many others). For most formats, you can just do a system-apropos
lookup with Quicklisp.
© 2022 - 2024 — McMap. All rights reserved.
*read-eval*
. lispworks.com/documentation/HyperSpec/Body/02_dhf.htm. That said, it's hard to be completely safe, since there are other kinds of macros that can be invoked by the reader. Rather recently, someone wrote up some good notes about safe input processing in Common Lisp (looking for it now). – Sheen