diff options
| author | Paul Eggert | 2011-06-12 19:02:16 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-12 19:02:16 -0700 |
| commit | 0fed43f396ce7838bdc591cec8b01be95fb9613a (patch) | |
| tree | f5ba32fcd7cce2a46f1fd1da24c45c0149552752 /src/data.c | |
| parent | 8fd02eb7d30a7e0e98cc863e0f3cb81a954fe8a9 (diff) | |
| download | emacs-0fed43f396ce7838bdc591cec8b01be95fb9613a.tar.gz emacs-0fed43f396ce7838bdc591cec8b01be95fb9613a.zip | |
* 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.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 87 |
1 files changed, 43 insertions, 44 deletions
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. */) | |||
| 2148 | CHECK_CHARACTER (idx); | 2148 | CHECK_CHARACTER (idx); |
| 2149 | CHAR_TABLE_SET (array, idxval, newelt); | 2149 | CHAR_TABLE_SET (array, idxval, newelt); |
| 2150 | } | 2150 | } |
| 2151 | else if (STRING_MULTIBYTE (array)) | 2151 | else |
| 2152 | { | 2152 | { |
| 2153 | EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; | ||
| 2154 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; | ||
| 2155 | int c; | 2153 | int c; |
| 2156 | 2154 | ||
| 2157 | if (idxval < 0 || idxval >= SCHARS (array)) | 2155 | if (idxval < 0 || idxval >= SCHARS (array)) |
| @@ -2159,52 +2157,53 @@ bool-vector. IDX starts at 0. */) | |||
| 2159 | CHECK_CHARACTER (newelt); | 2157 | CHECK_CHARACTER (newelt); |
| 2160 | c = XFASTINT (newelt); | 2158 | c = XFASTINT (newelt); |
| 2161 | 2159 | ||
| 2162 | nbytes = SBYTES (array); | 2160 | if (STRING_MULTIBYTE (array)) |
| 2163 | |||
| 2164 | idxval_byte = string_char_to_byte (array, idxval); | ||
| 2165 | p1 = SDATA (array) + idxval_byte; | ||
| 2166 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); | ||
| 2167 | new_bytes = CHAR_STRING (c, p0); | ||
| 2168 | if (prev_bytes != new_bytes) | ||
| 2169 | { | 2161 | { |
| 2170 | /* We must relocate the string data. */ | 2162 | EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; |
| 2171 | EMACS_INT nchars = SCHARS (array); | 2163 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; |
| 2172 | unsigned char *str; | 2164 | |
| 2173 | USE_SAFE_ALLOCA; | 2165 | nbytes = SBYTES (array); |
| 2174 | 2166 | idxval_byte = string_char_to_byte (array, idxval); | |
| 2175 | SAFE_ALLOCA (str, unsigned char *, nbytes); | ||
| 2176 | memcpy (str, SDATA (array), nbytes); | ||
| 2177 | allocate_string_data (XSTRING (array), nchars, | ||
| 2178 | nbytes + new_bytes - prev_bytes); | ||
| 2179 | memcpy (SDATA (array), str, idxval_byte); | ||
| 2180 | p1 = SDATA (array) + idxval_byte; | 2167 | p1 = SDATA (array) + idxval_byte; |
| 2181 | memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, | 2168 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); |
| 2182 | nbytes - (idxval_byte + prev_bytes)); | 2169 | new_bytes = CHAR_STRING (c, p0); |
| 2183 | SAFE_FREE (); | 2170 | if (prev_bytes != new_bytes) |
| 2184 | clear_string_char_byte_cache (); | 2171 | { |
| 2172 | /* We must relocate the string data. */ | ||
| 2173 | EMACS_INT nchars = SCHARS (array); | ||
| 2174 | unsigned char *str; | ||
| 2175 | USE_SAFE_ALLOCA; | ||
| 2176 | |||
| 2177 | SAFE_ALLOCA (str, unsigned char *, nbytes); | ||
| 2178 | memcpy (str, SDATA (array), nbytes); | ||
| 2179 | allocate_string_data (XSTRING (array), nchars, | ||
| 2180 | nbytes + new_bytes - prev_bytes); | ||
| 2181 | memcpy (SDATA (array), str, idxval_byte); | ||
| 2182 | p1 = SDATA (array) + idxval_byte; | ||
| 2183 | memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, | ||
| 2184 | nbytes - (idxval_byte + prev_bytes)); | ||
| 2185 | SAFE_FREE (); | ||
| 2186 | clear_string_char_byte_cache (); | ||
| 2187 | } | ||
| 2188 | while (new_bytes--) | ||
| 2189 | *p1++ = *p0++; | ||
| 2185 | } | 2190 | } |
| 2186 | while (new_bytes--) | 2191 | else |
| 2187 | *p1++ = *p0++; | ||
| 2188 | } | ||
| 2189 | else | ||
| 2190 | { | ||
| 2191 | if (idxval < 0 || idxval >= SCHARS (array)) | ||
| 2192 | args_out_of_range (array, idx); | ||
| 2193 | CHECK_NUMBER (newelt); | ||
| 2194 | |||
| 2195 | if (XINT (newelt) >= 0 && ! SINGLE_BYTE_CHAR_P (XINT (newelt))) | ||
| 2196 | { | 2192 | { |
| 2197 | int i; | 2193 | if (! SINGLE_BYTE_CHAR_P (c)) |
| 2198 | 2194 | { | |
| 2199 | for (i = SBYTES (array) - 1; i >= 0; i--) | 2195 | int i; |
| 2200 | if (SREF (array, i) >= 0x80) | 2196 | |
| 2201 | args_out_of_range (array, newelt); | 2197 | for (i = SBYTES (array) - 1; i >= 0; i--) |
| 2202 | /* ARRAY is an ASCII string. Convert it to a multibyte | 2198 | if (SREF (array, i) >= 0x80) |
| 2203 | string, and try `aset' again. */ | 2199 | args_out_of_range (array, newelt); |
| 2204 | STRING_SET_MULTIBYTE (array); | 2200 | /* ARRAY is an ASCII string. Convert it to a multibyte |
| 2205 | return Faset (array, idx, newelt); | 2201 | string, and try `aset' again. */ |
| 2202 | STRING_SET_MULTIBYTE (array); | ||
| 2203 | return Faset (array, idx, newelt); | ||
| 2204 | } | ||
| 2205 | SSET (array, idxval, c); | ||
| 2206 | } | 2206 | } |
| 2207 | SSET (array, idxval, XINT (newelt)); | ||
| 2208 | } | 2207 | } |
| 2209 | 2208 | ||
| 2210 | return newelt; | 2209 | return newelt; |