diff options
| author | Paul Eggert | 2011-06-12 17:36:03 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-12 17:36:03 -0700 |
| commit | 13bdea59234b227bf8499a64352da3e5fd9e8c7b (patch) | |
| tree | deddcce496ffa4fdb6d5ffd45ec8c2c7c5c49d0c /src/data.c | |
| parent | d37ca62316e7526da7d75cc44c7a4cd8a6281bb5 (diff) | |
| download | emacs-13bdea59234b227bf8499a64352da3e5fd9e8c7b.tar.gz emacs-13bdea59234b227bf8499a64352da3e5fd9e8c7b.zip | |
Make sure a 64-bit char is never passed to CHAR_STRING.
Otherwise, CHAR_STRING would do the wrong thing on a 64-bit platform,
by silently ignoring the top 32 bits, allowing some values
that were far too large to be valid characters.
* character.h: Include <verify.h>.
(CHAR_STRING, CHAR_STRING_ADVANCE): Verify that the character
arguments are no wider than unsigned, as a compile-time check
to prevent future regressions in this area.
* data.c (Faset):
* editfns.c (Fchar_to_string, general_insert_function, Finsert_char):
(Fsubst_char_in_region):
* fns.c (concat):
* xdisp.c (decode_mode_spec_coding):
Adjust to CHAR_STRING's new requirement.
* editfns.c (Finsert_char, Fsubst_char_in_region):
* fns.c (concat): Check that character args are actually
characters. Without this test, these functions did the wrong
thing with wildly out-of-range values on 64-bit hosts.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/data.c b/src/data.c index 57d7753e393..3a08a7a8cd3 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2152,17 +2152,19 @@ bool-vector. IDX starts at 0. */) | |||
| 2152 | { | 2152 | { |
| 2153 | EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; | 2153 | EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; |
| 2154 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; | 2154 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; |
| 2155 | int c; | ||
| 2155 | 2156 | ||
| 2156 | if (idxval < 0 || idxval >= SCHARS (array)) | 2157 | if (idxval < 0 || idxval >= SCHARS (array)) |
| 2157 | args_out_of_range (array, idx); | 2158 | args_out_of_range (array, idx); |
| 2158 | CHECK_CHARACTER (newelt); | 2159 | CHECK_CHARACTER (newelt); |
| 2160 | c = XFASTINT (newelt); | ||
| 2159 | 2161 | ||
| 2160 | nbytes = SBYTES (array); | 2162 | nbytes = SBYTES (array); |
| 2161 | 2163 | ||
| 2162 | idxval_byte = string_char_to_byte (array, idxval); | 2164 | idxval_byte = string_char_to_byte (array, idxval); |
| 2163 | p1 = SDATA (array) + idxval_byte; | 2165 | p1 = SDATA (array) + idxval_byte; |
| 2164 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); | 2166 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); |
| 2165 | new_bytes = CHAR_STRING (XINT (newelt), p0); | 2167 | new_bytes = CHAR_STRING (c, p0); |
| 2166 | if (prev_bytes != new_bytes) | 2168 | if (prev_bytes != new_bytes) |
| 2167 | { | 2169 | { |
| 2168 | /* We must relocate the string data. */ | 2170 | /* We must relocate the string data. */ |