Fix bug uncovered by changing alloca to auto buffer.
* coding.c (growable_destination): New function. (produce_chars): Use it for sanity checks. Do not fiddle with dst_end if the source and destination are both nil, as it's the caller's responsibility to avoid overlap. * keyboard.c (read_decoded_event_from_main_queue): The destination must be MAX_MULTIBYTE_LENGTH times the max source length, not 4 times, to prevent decode_coding_c_string from trying to reallocate a destination. This removes the need for the FIXME. Fixes: debbugs:18410
This commit is contained in:
parent
d5e25ad17f
commit
4612d1eab7
3 changed files with 31 additions and 12 deletions
|
@ -1,5 +1,15 @@
|
|||
2014-09-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Fix bug uncovered by changing alloca to auto buffer (Bug#18410).
|
||||
* coding.c (growable_destination): New function.
|
||||
(produce_chars): Use it for sanity checks. Do not fiddle with
|
||||
dst_end if the source and destination are both nil, as it's
|
||||
the caller's responsibility to avoid overlap.
|
||||
* keyboard.c (read_decoded_event_from_main_queue):
|
||||
The destination must be MAX_MULTIBYTE_LENGTH times the max source
|
||||
length, not 4 times, to prevent decode_coding_c_string from trying
|
||||
to reallocate a destination. This removes the need for the FIXME.
|
||||
|
||||
* callproc.c (exec_failed) [DOS_NT]: Define a dummy.
|
||||
All callers simplified. Add a comment about exec_failed, vfork,
|
||||
and alloca.
|
||||
|
|
20
src/coding.c
20
src/coding.c
|
@ -690,6 +690,14 @@ CHECK_NATNUM_CDR (Lisp_Object x)
|
|||
XSETCDR (x, tmp);
|
||||
}
|
||||
|
||||
/* True if CODING's destination can be grown. */
|
||||
|
||||
static bool
|
||||
growable_destination (struct coding_system *coding)
|
||||
{
|
||||
return STRINGP (coding->dst_object) || BUFFERP (coding->dst_object);
|
||||
}
|
||||
|
||||
|
||||
/* Safely get one byte from the source text pointed by SRC which ends
|
||||
at SRC_END, and set C to that byte. If there are not enough bytes
|
||||
|
@ -7019,8 +7027,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
|
|||
int *buf = coding->charbuf;
|
||||
int *buf_end = buf + coding->charbuf_used;
|
||||
|
||||
if (EQ (coding->src_object, coding->dst_object))
|
||||
if (EQ (coding->src_object, coding->dst_object)
|
||||
&& ! NILP (coding->dst_object))
|
||||
{
|
||||
eassert (growable_destination (coding));
|
||||
coding_set_source (coding);
|
||||
dst_end = ((unsigned char *) coding->source) + coding->consumed;
|
||||
}
|
||||
|
@ -7059,6 +7069,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
|
|||
|
||||
if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
|
||||
{
|
||||
eassert (growable_destination (coding));
|
||||
if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
|
||||
/ MAX_MULTIBYTE_LENGTH)
|
||||
< to_nchars)
|
||||
|
@ -7103,7 +7114,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
|
|||
const unsigned char *src_end = src + coding->consumed;
|
||||
|
||||
if (EQ (coding->dst_object, coding->src_object))
|
||||
dst_end = (unsigned char *) src;
|
||||
{
|
||||
eassert (growable_destination (coding));
|
||||
dst_end = (unsigned char *) src;
|
||||
}
|
||||
if (coding->src_multibyte != coding->dst_multibyte)
|
||||
{
|
||||
if (coding->src_multibyte)
|
||||
|
@ -7119,6 +7133,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
|
|||
ONE_MORE_BYTE (c);
|
||||
if (dst == dst_end)
|
||||
{
|
||||
eassert (growable_destination (coding));
|
||||
if (EQ (coding->src_object, coding->dst_object))
|
||||
dst_end = (unsigned char *) src;
|
||||
if (dst == dst_end)
|
||||
|
@ -7149,6 +7164,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
|
|||
|
||||
if (dst >= dst_end - 1)
|
||||
{
|
||||
eassert (growable_destination (coding));
|
||||
if (EQ (coding->src_object, coding->dst_object))
|
||||
dst_end = (unsigned char *) src;
|
||||
if (dst >= dst_end - 1)
|
||||
|
|
|
@ -2355,22 +2355,15 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
|
|||
struct coding_system *coding
|
||||
= TERMINAL_KEYBOARD_CODING (terminal);
|
||||
unsigned char src[MAX_ENCODED_BYTES];
|
||||
unsigned char dest[4 * sizeof src];
|
||||
unsigned char dest[MAX_ENCODED_BYTES * MAX_MULTIBYTE_LENGTH];
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
src[i] = XINT (events[i]);
|
||||
if (meta_key != 2)
|
||||
for (i = 0; i < n; i++)
|
||||
src[i] &= ~0x80;
|
||||
|
||||
/* FIXME: For some reason decode_coding_c_string requires a
|
||||
fresh output buffer each time, and reusing the old buffer can
|
||||
make Emacs dump core. Avoid triggering the problem for now
|
||||
by allocating a new buffer each time through the loop. */
|
||||
bool please_fixme = true;
|
||||
coding->destination = please_fixme ? alloca (n * 4) : dest;
|
||||
|
||||
coding->dst_bytes = n * 4;
|
||||
coding->destination = dest;
|
||||
coding->dst_bytes = sizeof dest;
|
||||
decode_coding_c_string (coding, src, n, Qnil);
|
||||
eassert (coding->produced_char <= n);
|
||||
if (coding->produced_char == 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue