# HG changeset patch # User Aidan Kehoe # Date 1270304852 -3600 # Node ID b51c2079ec8e6aebd8325ad81372e96a3d311807 # Parent b36d089cbed585010b8362964ae444bb4b75b928 Be much more careful about resizing a string argument, #'fill 2010-04-03 Aidan Kehoe * fns.c (Ffill): Be much more careful about resizing a string argument, update pointers to within the string data that may have been relocated with the string resize. Fixes a test hang reported by Vin Shelton; thanks, Vin. diff -r b36d089cbed5 -r b51c2079ec8e src/ChangeLog --- a/src/ChangeLog Fri Apr 02 13:23:31 2010 +0100 +++ b/src/ChangeLog Sat Apr 03 15:27:32 2010 +0100 @@ -1,3 +1,11 @@ +2010-04-03 Aidan Kehoe + + * fns.c (Ffill): + Be much more careful about resizing a string argument, update + pointers to within the string data that may have been relocated + with the string resize. Fixes a test hang reported by Vin Shelton; + thanks, Vin. + 2010-04-02 Aidan Kehoe * fns.c (FsortX, Ffill): diff -r b36d089cbed5 -r b51c2079ec8e src/fns.c --- a/src/fns.c Fri Apr 02 13:23:31 2010 +0100 +++ b/src/fns.c Sat Apr 03 15:27:32 2010 +0100 @@ -3795,10 +3795,9 @@ retry: if (STRINGP (sequence)) { - Bytecount old_bytecount, new_bytecount, item_bytecount; + Bytecount prefix_bytecount, item_bytecount, delta; Ibyte item_buf[MAX_ICHAR_LEN]; - Ibyte *p; - Ibyte *pend; + Ibyte *p, *pend; CHECK_CHAR_COERCE_INT (item); @@ -3808,17 +3807,26 @@ p = XSTRING_DATA (sequence); p = (Ibyte *) itext_n_addr (p, starting); - old_bytecount = p - XSTRING_DATA (sequence); + prefix_bytecount = p - XSTRING_DATA (sequence); ending = min (ending, string_char_length (sequence)); pend = (Ibyte *) itext_n_addr (p, ending - starting); - - new_bytecount = old_bytecount + (item_bytecount * (ending - starting)); - resize_string (sequence, -1, new_bytecount - old_bytecount); + delta = ((ending - starting) * item_bytecount) - (pend - p); + + /* Resize the string if the bytecount for the area being modified is + different. */ + if (delta) + { + resize_string (sequence, prefix_bytecount, delta); + /* No need to zero-terminate the string, resize_string has done + that for us. */ + p = XSTRING_DATA (sequence) + prefix_bytecount; + pend = p + ((ending - starting) * item_bytecount); + } for (; p < pend; p += item_bytecount) memcpy (p, item_buf, item_bytecount); - *p = '\0'; + init_string_ascii_begin (sequence); bump_string_modiff (sequence);