>From 9bf82b9f523366c9795c0ad14c26bcb2f7c2b625 Mon Sep 17 00:00:00 2001 From: Mario Domenech Goulart Date: Fri, 27 Jun 2014 17:43:38 -0300 Subject: [PATCH] C_substring_copy: use C_memmove instead of C_memcpy memcpy will screw things up when given the src and dest strings' memory area overlap (e.g., the same string object is given as src and dest argument), and that can cause problems in some string-copy! use cases. Fixes #1135. --- NEWS | 2 ++ chicken.h | 6 +++--- tests/srfi-13-tests.scm | 12 ++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index a9ded9e..c8ce427 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ - Unit tcp now implicitly depends on ports instead of extras. This may break programs which don't use modules and forgot to require extras but use procedures from it. + - SRFI-13: fix string-copy! in cases source and destination strings' + memory areas overlap (#1135). - Unit lolevel: - Restore long-lost but still documented "vector-like?" procedure (#983) diff --git a/chicken.h b/chicken.h index 4a3c77a..f5a103e 100644 --- a/chicken.h +++ b/chicken.h @@ -1260,9 +1260,9 @@ extern double trunc(double); #define C_i_char_greater_or_equal_p(x, y) C_mk_bool(C_character_code(x) >= C_character_code(y)) #define C_i_char_less_or_equal_p(x, y) C_mk_bool(C_character_code(x) <= C_character_code(y)) #define C_substring_copy(s1, s2, start1, end1, start2) \ - (C_memcpy((C_char *)C_data_pointer(s2) + C_unfix(start2), \ - (C_char *)C_data_pointer(s1) + C_unfix(start1), \ - C_unfix(end1) - C_unfix(start1) ), C_SCHEME_UNDEFINED) + (C_memmove((C_char *)C_data_pointer(s2) + C_unfix(start2), \ + (C_char *)C_data_pointer(s1) + C_unfix(start1), \ + C_unfix(end1) - C_unfix(start1) ), C_SCHEME_UNDEFINED) #define C_substring_compare(s1, s2, start1, start2, len) \ C_mk_bool(C_memcmp((C_char *)C_data_pointer(s1) + C_unfix(start1), \ (C_char *)C_data_pointer(s2) + C_unfix(start2), \ diff --git a/tests/srfi-13-tests.scm b/tests/srfi-13-tests.scm index 1262b82..8df378a 100644 --- a/tests/srfi-13-tests.scm +++ b/tests/srfi-13-tests.scm @@ -115,6 +115,18 @@ (let ((x (string-copy "abcdefg"))) (string-copy! x 2 "ZABCDEFG" 3 6) x)) + +;; From Guile. Thanks to Mark H Weaver. +(test "string-copy!: overlapping src and dest, moving right" + "aabce" + (let ((str (string-copy "abcde"))) + (string-copy! str 1 str 0 3) str)) + +(test "string-copy!: overlapping src and dest, moving left" + "bcdde" + (let ((str (string-copy "abcde"))) + (string-copy! str 0 str 1 4) str)) + (test "string-take" "Pete S" (string-take "Pete Szilagyi" 6)) (test "string-take" "" (string-take "Pete Szilagyi" 0)) (test "string-take" "Pete Szilagyi" (string-take "Pete Szilagyi" 13)) -- 1.7.10.4