~ chicken-core (chicken-5) 0e97b648407d750f1e476e3c193e136126558346
commit 0e97b648407d750f1e476e3c193e136126558346 Author: siiky <github-siiky@net-c.cat> AuthorDate: Mon Mar 11 12:15:44 2024 +0100 Commit: Mario Domenech Goulart <mario@parenteses.org> CommitDate: Tue Mar 12 20:41:44 2024 +0100 Add bounds-checks to substring=? and substring-ci=? Because the `start1`/`start2`/`n` parameters were not checked to be within bounds, it was possible to access arbitrary memory outside of the given strings. This could lead to wrong results (returning #t/#f when the opposite was true), or possibly crashing the program. Signed-off-by: felix <felix@call-with-current-continuation.org> Signed-off-by: Mario Domenech Goulart <mario@parenteses.org> diff --git a/data-structures.scm b/data-structures.scm index 8563fba2..642d2a59 100644 --- a/data-structures.scm +++ b/data-structures.scm @@ -155,11 +155,13 @@ (define (##sys#substring=? s1 s2 start1 start2 n) (##sys#check-string s1 'substring=?) (##sys#check-string s2 'substring=?) - (let ((len (or n - (fxmin (fx- (##sys#size s1) start1) - (fx- (##sys#size s2) start2) ) ) ) ) - (##sys#check-fixnum start1 'substring=?) - (##sys#check-fixnum start2 'substring=?) + (##sys#check-range start1 0 (##sys#size s1) 'substring=?) + (##sys#check-range start2 0 (##sys#size s2) 'substring=?) + (let* ((maxlen (fxmin (fx- (##sys#size s1) start1) + (fx- (##sys#size s2) start2))) + (len (if n + (begin (##sys#check-range n 0 maxlen 'substring=?) n) + maxlen))) (##core#inline "C_substring_compare" s1 s2 start1 start2 len) ) ) (define (substring=? s1 s2 #!optional (start1 0) (start2 0) len) @@ -168,11 +170,13 @@ (define (##sys#substring-ci=? s1 s2 start1 start2 n) (##sys#check-string s1 'substring-ci=?) (##sys#check-string s2 'substring-ci=?) - (let ((len (or n - (fxmin (fx- (##sys#size s1) start1) - (fx- (##sys#size s2) start2) ) ) ) ) - (##sys#check-fixnum start1 'substring-ci=?) - (##sys#check-fixnum start2 'substring-ci=?) + (##sys#check-range start1 0 (##sys#size s1) 'substring-ci=?) + (##sys#check-range start2 0 (##sys#size s2) 'substring-ci=?) + (let* ((maxlen (fxmin (fx- (##sys#size s1) start1) + (fx- (##sys#size s2) start2))) + (len (if n + (begin (##sys#check-range n 0 maxlen 'substring-ci=?) n) + maxlen))) (##core#inline "C_substring_compare_case_insensitive" s1 s2 start1 start2 len) ) ) diff --git a/tests/data-structures-tests.scm b/tests/data-structures-tests.scm index 1d7820df..17a3dd58 100644 --- a/tests/data-structures-tests.scm +++ b/tests/data-structures-tests.scm @@ -50,6 +50,18 @@ (assert (not (substring-index-ci "o\x00bar" "foo\x00baz"))) (assert (= 0 (substring-index "" ""))) (assert (= 1 (substring-index "" "a" 1))) +(assert-error (substring=? "a" "a" 2)) +(assert-error (substring=? "a" "a" -2)) +(assert-error (substring=? "a" "a" 0 2)) +(assert-error (substring=? "a" "a" 0 -2)) +(assert-error (substring=? "a" "a" 0 0 2)) +(assert-error (substring=? "a" "a" 0 0 -2)) +(assert-error (substring-ci=? "a" "a" 2)) +(assert-error (substring-ci=? "a" "a" -2)) +(assert-error (substring-ci=? "a" "a" 0 2)) +(assert-error (substring-ci=? "a" "a" 0 -2)) +(assert-error (substring-ci=? "a" "a" 0 0 2)) +(assert-error (substring-ci=? "a" "a" 0 0 -2)) (assert-error (substring-index "" "a" 2)) (assert-error (substring-index "a" "b" 2)) (assert (not (substring-index "a" "b" 1)))Trap