~ chicken-core (chicken-5) 1be37b85437c8e0644964ed6ca7b54a1ecfd29b5
commit 1be37b85437c8e0644964ed6ca7b54a1ecfd29b5 Author: Jim Ursetto <zbigniewsz@gmail.com> AuthorDate: Mon Apr 23 12:56:22 2012 -0500 Commit: Peter Bex <peter.bex@xs4all.nl> CommitDate: Mon Apr 23 20:04:33 2012 +0200 Also use C_memcasecmp for case-insensitive substring comparisons (#808) Signed-off-by: Peter Bex <peter.bex@xs4all.nl> diff --git a/chicken.h b/chicken.h index 3854c0c0..837a51cf 100644 --- a/chicken.h +++ b/chicken.h @@ -1118,7 +1118,7 @@ extern double trunc(double); (C_char *)C_data_pointer(s2) + C_unfix(start2), \ C_unfix(len) ) == 0) #define C_substring_compare_case_insensitive(s1, s2, start1, start2, len) \ - C_mk_bool(C_strncasecmp((C_char *)C_data_pointer(s1) + C_unfix(start1), \ + C_mk_bool(C_memcasecmp((C_char *)C_data_pointer(s1) + C_unfix(start1), \ (C_char *)C_data_pointer(s2) + C_unfix(start2), \ C_unfix(len) ) == 0) /* this does not use C_mutate: */ @@ -2112,12 +2112,10 @@ C_inline int C_memcasecmp(const char *x, const char *y, unsigned int len) const unsigned char *ux = (const unsigned char *)x; const unsigned char *uy = (const unsigned char *)y; - if (len == 0) return 0; - - do { + while (len--) { if (tolower(*ux++) != tolower(*uy++)) return (tolower(*--ux) - tolower(*--uy)); - } while(--len != 0); + } return 0; } diff --git a/data-structures.scm b/data-structures.scm index 058bc511..2ed9102a 100644 --- a/data-structures.scm +++ b/data-structures.scm @@ -26,11 +26,7 @@ (declare - (unit data-structures) - (foreign-declare #<<EOF -#define C_mem_compare(to, from, n) C_fix(C_memcmp(C_c_string(to), C_c_string(from), C_unfix(n))) -EOF -) ) + (unit data-structures)) (include "common-declarations.scm") @@ -352,7 +348,7 @@ EOF (let ((len1 (##sys#size s1)) (len2 (##sys#size s2)) ) (let* ((len-diff (fx- len1 len2)) - (cmp (##core#inline "C_mem_compare" s1 s2 (if (fx< len-diff 0) len1 len2)))) + (cmp (##core#inline "C_string_compare" s1 s2 (if (fx< len-diff 0) len1 len2)))) (if (fx= cmp 0) len-diff cmp)))) diff --git a/tests/data-structures-tests.scm b/tests/data-structures-tests.scm index df4b5591..b0f8794b 100644 --- a/tests/data-structures-tests.scm +++ b/tests/data-structures-tests.scm @@ -1,6 +1,5 @@ ;;;; data-structures-tests.scm - (use data-structures) (let ((alist '((foo . 123) ("bar" . "baz")))) @@ -15,4 +14,26 @@ (alist-update 'foo 999 alist) (assert (= (alist-ref 'foo alist) 123)) (assert (eq? 'yep (alist-ref 'qux (alist-update 'qux 'yep alist)))) - (assert (eq? 'ok (alist-ref "bar" (alist-update "bar" 'ok alist equal?) equal?)))) \ No newline at end of file + (assert (eq? 'ok (alist-ref "bar" (alist-update "bar" 'ok alist equal?) equal?)))) + +;; #808: strings with embedded nul bytes should not be compared +;; with ASCIIZ string comparison functions +(assert (substring=? "foo\x00a" "foo\x00a" 1 1)) +(assert (substring-ci=? "foo\x00a" "foo\x00a" 1 1)) +(assert (substring-ci=? "foo\x00a" "foo\x00A" 1 1)) +(assert (= 2 (substring-index "o\x00bar" "foo\x00bar"))) +(assert (= 2 (substring-index-ci "o\x00bar" "foo\x00bar"))) +(assert (= 2 (substring-index-ci "o\x00bar" "foo\x00BAR"))) +(assert (not (substring=? "foo\x00a" "foo\x00b" 1 1))) +(assert (not (substring-ci=? "foo\x00a" "foo\x00b" 1 1))) +(assert (not (substring-index "o\x00bar" "foo\x00baz"))) +(assert (not (substring-index-ci "o\x00bar" "foo\x00baz"))) +(assert (= 0 (string-compare3 "foo\x00a" "foo\x00a"))) +(assert (> 0 (string-compare3 "foo\x00a" "foo\x00b"))) +(assert (< 0 (string-compare3 "foo\x00b" "foo\x00a"))) +(assert (= 0 (string-compare3-ci "foo\x00a" "foo\x00a"))) +(assert (= 0 (string-compare3-ci "foo\x00a" "foo\x00A"))) +(assert (> 0 (string-compare3-ci "foo\x00a" "foo\x00b"))) +(assert (> 0 (string-compare3-ci "foo\x00A" "foo\x00b"))) +(assert (< 0 (string-compare3-ci "foo\x00b" "foo\x00a"))) +(assert (< 0 (string-compare3-ci "foo\x00b" "foo\x00A"))) diff --git a/tests/library-tests.scm b/tests/library-tests.scm index f9cb61d2..a7c17e51 100644 --- a/tests/library-tests.scm +++ b/tests/library-tests.scm @@ -220,8 +220,14 @@ (assert (equal? '#${abc} '#${ab0c})) (assert (equal? '#${a b c} '#${0a0b0c})) -;; #800: blobs and strings with embedded nul bytes should not be compared +;; #808: blobs and strings with embedded nul bytes should not be compared ;; with ASCIIZ string comparison functions +(assert (equal? '#${a b 0 c} '#${a b 0 c})) +(assert (blob=? '#${a b 0 c} '#${a b 0 c})) +(assert (equal=? "foo\x00a" "foo\x00a")) +(assert (string=? "foo\x00a" "foo\x00a")) +(assert (string-ci=? "foo\x00a" "foo\x00a")) +(assert (string-ci=? "foo\x00a" "foo\x00A")) (assert (not (equal? '#${a b 0 c} '#${a b 0 d}))) (assert (not (blob=? '#${a b 0 c} '#${a b 0 d}))) (assert (not (equal=? "foo\x00a" "foo\x00b")))Trap