From 0fed43f396ce7838bdc591cec8b01be95fb9613a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 12 Jun 2011 19:02:16 -0700 Subject: [PATCH] * data.c (Faset): If ARRAY is a string, check that NEWELT is a char. Without this fix, on a 64-bit host (aset S 0 4294967386) would incorrectly succeed when S was a string, because 4294967386 was truncated before it was used. --- src/ChangeLog | 5 +++ src/data.c | 87 +++++++++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index db01d9f291f..9b0ff3e7339 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2011-06-13 Paul Eggert + * data.c (Faset): If ARRAY is a string, check that NEWELT is a char. + Without this fix, on a 64-bit host (aset S 0 4294967386) would + incorrectly succeed when S was a string, because 4294967386 was + truncated before it was used. + * chartab.c (Fchar_table_range): Use CHARACTERP to check range. Otherwise, an out-of-range integer could cause undefined behavior on a 64-bit host. diff --git a/src/data.c b/src/data.c index 3a08a7a8cd3..a239a89c2d4 100644 --- a/src/data.c +++ b/src/data.c @@ -2148,10 +2148,8 @@ bool-vector. IDX starts at 0. */) CHECK_CHARACTER (idx); CHAR_TABLE_SET (array, idxval, newelt); } - else if (STRING_MULTIBYTE (array)) + else { - EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; - unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; int c; if (idxval < 0 || idxval >= SCHARS (array)) @@ -2159,52 +2157,53 @@ bool-vector. IDX starts at 0. */) CHECK_CHARACTER (newelt); c = XFASTINT (newelt); - nbytes = SBYTES (array); - - idxval_byte = string_char_to_byte (array, idxval); - p1 = SDATA (array) + idxval_byte; - prev_bytes = BYTES_BY_CHAR_HEAD (*p1); - new_bytes = CHAR_STRING (c, p0); - if (prev_bytes != new_bytes) + if (STRING_MULTIBYTE (array)) { - /* We must relocate the string data. */ - EMACS_INT nchars = SCHARS (array); - unsigned char *str; - USE_SAFE_ALLOCA; - - SAFE_ALLOCA (str, unsigned char *, nbytes); - memcpy (str, SDATA (array), nbytes); - allocate_string_data (XSTRING (array), nchars, - nbytes + new_bytes - prev_bytes); - memcpy (SDATA (array), str, idxval_byte); + EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; + unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; + + nbytes = SBYTES (array); + idxval_byte = string_char_to_byte (array, idxval); p1 = SDATA (array) + idxval_byte; - memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, - nbytes - (idxval_byte + prev_bytes)); - SAFE_FREE (); - clear_string_char_byte_cache (); + prev_bytes = BYTES_BY_CHAR_HEAD (*p1); + new_bytes = CHAR_STRING (c, p0); + if (prev_bytes != new_bytes) + { + /* We must relocate the string data. */ + EMACS_INT nchars = SCHARS (array); + unsigned char *str; + USE_SAFE_ALLOCA; + + SAFE_ALLOCA (str, unsigned char *, nbytes); + memcpy (str, SDATA (array), nbytes); + allocate_string_data (XSTRING (array), nchars, + nbytes + new_bytes - prev_bytes); + memcpy (SDATA (array), str, idxval_byte); + p1 = SDATA (array) + idxval_byte; + memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, + nbytes - (idxval_byte + prev_bytes)); + SAFE_FREE (); + clear_string_char_byte_cache (); + } + while (new_bytes--) + *p1++ = *p0++; } - while (new_bytes--) - *p1++ = *p0++; - } - else - { - if (idxval < 0 || idxval >= SCHARS (array)) - args_out_of_range (array, idx); - CHECK_NUMBER (newelt); - - if (XINT (newelt) >= 0 && ! SINGLE_BYTE_CHAR_P (XINT (newelt))) + else { - int i; - - for (i = SBYTES (array) - 1; i >= 0; i--) - if (SREF (array, i) >= 0x80) - args_out_of_range (array, newelt); - /* ARRAY is an ASCII string. Convert it to a multibyte - string, and try `aset' again. */ - STRING_SET_MULTIBYTE (array); - return Faset (array, idx, newelt); + if (! SINGLE_BYTE_CHAR_P (c)) + { + int i; + + for (i = SBYTES (array) - 1; i >= 0; i--) + if (SREF (array, i) >= 0x80) + args_out_of_range (array, newelt); + /* ARRAY is an ASCII string. Convert it to a multibyte + string, and try `aset' again. */ + STRING_SET_MULTIBYTE (array); + return Faset (array, idx, newelt); + } + SSET (array, idxval, c); } - SSET (array, idxval, XINT (newelt)); } return newelt; -- 2.39.2