~ chicken-core (chicken-5) cd1b9775005ebe220ba11265dbf5396142e65f26
commit cd1b9775005ebe220ba11265dbf5396142e65f26 Author: Peter Bex <peter.bex@xs4all.nl> AuthorDate: Sun Sep 22 11:37:09 2013 +0200 Commit: Peter Bex <peter.bex@xs4all.nl> CommitDate: Tue Sep 24 09:05:48 2013 +0200 Read no more than the buffer length when a length of #f is passed in Signed-off-by: Mario Domenech Goulart <mario.goulart@gmail.com> Signed-off-by: Peter Bex <peter.bex@xs4all.nl> diff --git a/NEWS b/NEWS index 5b3cfdb3..d4e65e98 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ 4.8.3 +- Security fixes + - read-string! no longer reads beyond its buffer when length is #f. + - Runtime system - The procedure trace buffer has been made resizable. diff --git a/extras.scm b/extras.scm index 49ab5cf2..8f17e1f3 100644 --- a/extras.scm +++ b/extras.scm @@ -176,10 +176,10 @@ (define (read-string! n dest #!optional (port ##sys#standard-input) (start 0)) (##sys#check-input-port port #t 'read-string!) (##sys#check-string dest 'read-string!) - (when n - (##sys#check-exact n 'read-string!) - (when (fx> (fx+ start n) (##sys#size dest)) - (set! n (fx- (##sys#size dest) start)))) + (when n (##sys#check-exact n 'read-string!)) + (let ((dest-size (##sys#size dest))) + (unless (and n (fx<= (fx+ start n) dest-size)) + (set! n (fx- dest-size start)))) (##sys#check-exact start 'read-string!) (##sys#read-string! n dest port start) ) diff --git a/tests/port-tests.scm b/tests/port-tests.scm index 409c552a..bd7c8586 100644 --- a/tests/port-tests.scm +++ b/tests/port-tests.scm @@ -295,7 +295,49 @@ EOF (test-group "read-line string port position tests" -(test-port-position read-string-line/pos)) + (test-port-position read-string-line/pos)) + +(test-group "read-string!" + (let ((in (open-input-string "1234567890")) + (buf (make-string 5))) + (test-equal "read-string! won't read past buffer if given #f" + (read-string! #f buf in) + 5) + (test-equal "read-string! reads the requested bytes with #f" + buf + "12345") + (test-equal "read-string! won't read past buffer if given #f and offset" + (read-string! #f buf in 3) + 2) + (test-equal "read-string! reads the requested bytes with #f and offset" + buf + "12367") + (test-equal "read-string! reads until the end correctly" + (read-string! #f buf in) + 3) + (test-equal "read-string! leaves the buffer's tail intact" + buf + "89067")) + (let ((in (open-input-string "1234567890")) + (buf (make-string 5))) + (test-equal "read-string! won't read past buffer if given size" + (read-string! 10 buf in) + 5) + (test-equal "read-string! reads the requested bytes with buffer size" + buf + "12345") + (test-equal "read-string! won't read past buffer if given size and offset" + (read-string! 10 buf in 3) + 2) + (test-equal "read-string! reads the requested bytes with buffer size and offset" + buf + "12367") + (test-equal "read-string! reads until the end correctly with buffer size" + (read-string! 10 buf in) + 3) + (test-equal "read-string! leaves the buffer's tail intact" + buf + "89067"))) ;; Disabled because it requires `echo -n` for ;; the EOF test, and that is not available on all systems.Trap