Mercurial > hg > xemacs-beta
changeset 5187:b51c2079ec8e
Be much more careful about resizing a string argument, #'fill
2010-04-03 Aidan Kehoe <kehoea@parhasard.net>
* 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.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 03 Apr 2010 15:27:32 +0100 |
parents | b36d089cbed5 |
children | 000287f8053b |
files | src/ChangeLog src/fns.c |
diffstat | 2 files changed, 24 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- 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 <kehoea@parhasard.net> + + * 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 <kehoea@parhasard.net> * fns.c (FsortX, Ffill):
--- 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);