comparison src/fns.c @ 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 039d9a7f2e6d
children 71ee43b8a74d
comparison
equal deleted inserted replaced
5186:b36d089cbed5 5187:b51c2079ec8e
3793 } 3793 }
3794 3794
3795 retry: 3795 retry:
3796 if (STRINGP (sequence)) 3796 if (STRINGP (sequence))
3797 { 3797 {
3798 Bytecount old_bytecount, new_bytecount, item_bytecount; 3798 Bytecount prefix_bytecount, item_bytecount, delta;
3799 Ibyte item_buf[MAX_ICHAR_LEN]; 3799 Ibyte item_buf[MAX_ICHAR_LEN];
3800 Ibyte *p; 3800 Ibyte *p, *pend;
3801 Ibyte *pend;
3802 3801
3803 CHECK_CHAR_COERCE_INT (item); 3802 CHECK_CHAR_COERCE_INT (item);
3804 3803
3805 CHECK_LISP_WRITEABLE (sequence); 3804 CHECK_LISP_WRITEABLE (sequence);
3806 sledgehammer_check_ascii_begin (sequence); 3805 sledgehammer_check_ascii_begin (sequence);
3807 item_bytecount = set_itext_ichar (item_buf, XCHAR (item)); 3806 item_bytecount = set_itext_ichar (item_buf, XCHAR (item));
3808 3807
3809 p = XSTRING_DATA (sequence); 3808 p = XSTRING_DATA (sequence);
3810 p = (Ibyte *) itext_n_addr (p, starting); 3809 p = (Ibyte *) itext_n_addr (p, starting);
3811 old_bytecount = p - XSTRING_DATA (sequence); 3810 prefix_bytecount = p - XSTRING_DATA (sequence);
3812 3811
3813 ending = min (ending, string_char_length (sequence)); 3812 ending = min (ending, string_char_length (sequence));
3814 pend = (Ibyte *) itext_n_addr (p, ending - starting); 3813 pend = (Ibyte *) itext_n_addr (p, ending - starting);
3815 3814 delta = ((ending - starting) * item_bytecount) - (pend - p);
3816 new_bytecount = old_bytecount + (item_bytecount * (ending - starting)); 3815
3817 resize_string (sequence, -1, new_bytecount - old_bytecount); 3816 /* Resize the string if the bytecount for the area being modified is
3817 different. */
3818 if (delta)
3819 {
3820 resize_string (sequence, prefix_bytecount, delta);
3821 /* No need to zero-terminate the string, resize_string has done
3822 that for us. */
3823 p = XSTRING_DATA (sequence) + prefix_bytecount;
3824 pend = p + ((ending - starting) * item_bytecount);
3825 }
3818 3826
3819 for (; p < pend; p += item_bytecount) 3827 for (; p < pend; p += item_bytecount)
3820 memcpy (p, item_buf, item_bytecount); 3828 memcpy (p, item_buf, item_bytecount);
3821 *p = '\0'; 3829
3822 3830
3823 init_string_ascii_begin (sequence); 3831 init_string_ascii_begin (sequence);
3824 bump_string_modiff (sequence); 3832 bump_string_modiff (sequence);
3825 sledgehammer_check_ascii_begin (sequence); 3833 sledgehammer_check_ascii_begin (sequence);
3826 } 3834 }