>From 21c4b28408144cf24b378b782a6e19c9b7d14ac9 Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Sun, 22 Apr 2012 15:49:45 +0200 Subject: [PATCH] Fix #808; use memcmp instead of strncmp for comparing blobs and Scheme strings, and include our own "memcasecmp" to replace strncasecmp --- chicken.h | 18 ++++++++++++++++-- tests/library-tests.scm | 11 +++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/chicken.h b/chicken.h index 8b1d751..3854c0c 100644 --- a/chicken.h +++ b/chicken.h @@ -1156,9 +1156,9 @@ extern double trunc(double); (C_memcpy(C_pointer_address(to) + C_unfix(toff), C_pointer_address(from) + C_unfix(foff), \ C_unfix(n)), C_SCHEME_UNDEFINED) #define C_set_memory(to, c, n) (C_memset(C_data_pointer(to), C_character_code(c), C_unfix(n)), C_SCHEME_UNDEFINED) -#define C_string_compare(to, from, n) C_fix(C_strncmp(C_c_string(to), C_c_string(from), C_unfix(n))) +#define C_string_compare(to, from, n) C_fix(C_memcmp(C_c_string(to), C_c_string(from), C_unfix(n))) #define C_string_compare_case_insensitive(from, to, n) \ - C_fix(C_strncasecmp(C_c_string(from), C_c_string(to), C_unfix(n))) + C_fix(C_memcasecmp(C_c_string(from), C_c_string(to), C_unfix(n))) #define C_rename_file(old, new) C_fix(rename(C_c_string(old), C_c_string(new))) #define C_delete_file(fname) C_fix(remove(C_c_string(fname))) #define C_poke_double(b, i, n) (((double *)C_data_pointer(b))[ C_unfix(i) ] = C_c_double(n), C_SCHEME_UNDEFINED) @@ -2106,6 +2106,20 @@ C_inline C_word C_u_i_string_equal_p(C_word x, C_word y) && !C_memcmp((char *)C_data_pointer(x), (char *)C_data_pointer(y), n)); } +/* Like memcmp but case insensitive (to strncasecmp as memcmp is to strncmp) */ +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 { + if (tolower(*ux++) != tolower(*uy++)) + return (tolower(*--ux) - tolower(*--uy)); + } while(--len != 0); + return 0; +} C_inline C_word C_i_eqvp(C_word x, C_word y) { diff --git a/tests/library-tests.scm b/tests/library-tests.scm index fab5f00..f9cb61d 100644 --- a/tests/library-tests.scm +++ b/tests/library-tests.scm @@ -220,6 +220,17 @@ (assert (equal? '#${abc} '#${ab0c})) (assert (equal? '#${a b c} '#${0a0b0c})) +;; #800: blobs and strings with embedded nul bytes should not be compared +;; with ASCIIZ string comparison functions +(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"))) +(assert (not (string=? "foo\x00a" "foo\x00b"))) +(assert (not (string-ci=? "foo\x00a" "foo\x00b"))) +(assert (string? "foo\x00b" "foo\x00a")) +(assert (string-ci? "foo\x00b" "foo\x00A")) ;;; getter-with-setter -- 1.7.9.1