chicken-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add bounds-checks to substring=? and substring-ci=?


From: siiky
Subject: [PATCH] Add bounds-checks to substring=? and substring-ci=?
Date: Sun, 10 Mar 2024 15:09:25 +0000
User-agent: Mozilla Thunderbird Beta

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.
---
 data-structures.scm             | 24 ++++++++++++++----------
 tests/data-structures-tests.scm | 12 ++++++++++++
 2 files changed, 26 insertions(+), 10 deletions(-)

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)))
-- 
2.43.0






reply via email to

[Prev in Thread] Current Thread [Next in Thread]