mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-11 05:51:21 -08:00
* 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.
This commit is contained in:
parent
8fd02eb7d3
commit
0fed43f396
2 changed files with 46 additions and 42 deletions
|
|
@ -1,5 +1,10 @@
|
|||
2011-06-13 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* 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.
|
||||
|
|
|
|||
83
src/data.c
83
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;
|
||||
EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes;
|
||||
unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
|
||||
|
||||
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);
|
||||
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 ();
|
||||
}
|
||||
while (new_bytes--)
|
||||
*p1++ = *p0++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idxval < 0 || idxval >= SCHARS (array))
|
||||
args_out_of_range (array, idx);
|
||||
CHECK_NUMBER (newelt);
|
||||
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;
|
||||
|
||||
if (XINT (newelt) >= 0 && ! SINGLE_BYTE_CHAR_P (XINT (newelt)))
|
||||
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++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
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);
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue