aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-09-07 15:27:59 -0700
committerPaul Eggert2014-09-07 15:27:59 -0700
commit4612d1eab721a1010312382d1048c8b3a67b18fa (patch)
treee0c89c15723fce2430853d3eddb9535ce0ad9e38 /src
parentd5e25ad17f871ed7837fcc5277efce762c112f2a (diff)
downloademacs-4612d1eab721a1010312382d1048c8b3a67b18fa.tar.gz
emacs-4612d1eab721a1010312382d1048c8b3a67b18fa.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/coding.c20
-rw-r--r--src/keyboard.c13
3 files changed, 31 insertions, 12 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 88ab1eedca8..2654abd32d4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,15 @@
12014-09-07 Paul Eggert <eggert@cs.ucla.edu> 12014-09-07 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Fix bug uncovered by changing alloca to auto buffer (Bug#18410).
4 * coding.c (growable_destination): New function.
5 (produce_chars): Use it for sanity checks. Do not fiddle with
6 dst_end if the source and destination are both nil, as it's
7 the caller's responsibility to avoid overlap.
8 * keyboard.c (read_decoded_event_from_main_queue):
9 The destination must be MAX_MULTIBYTE_LENGTH times the max source
10 length, not 4 times, to prevent decode_coding_c_string from trying
11 to reallocate a destination. This removes the need for the FIXME.
12
3 * callproc.c (exec_failed) [DOS_NT]: Define a dummy. 13 * callproc.c (exec_failed) [DOS_NT]: Define a dummy.
4 All callers simplified. Add a comment about exec_failed, vfork, 14 All callers simplified. Add a comment about exec_failed, vfork,
5 and alloca. 15 and alloca.
diff --git a/src/coding.c b/src/coding.c
index 84b774b4355..ed107a297ba 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -690,6 +690,14 @@ CHECK_NATNUM_CDR (Lisp_Object x)
690 XSETCDR (x, tmp); 690 XSETCDR (x, tmp);
691} 691}
692 692
693/* True if CODING's destination can be grown. */
694
695static bool
696growable_destination (struct coding_system *coding)
697{
698 return STRINGP (coding->dst_object) || BUFFERP (coding->dst_object);
699}
700
693 701
694/* Safely get one byte from the source text pointed by SRC which ends 702/* Safely get one byte from the source text pointed by SRC which ends
695 at SRC_END, and set C to that byte. If there are not enough bytes 703 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,
7019 int *buf = coding->charbuf; 7027 int *buf = coding->charbuf;
7020 int *buf_end = buf + coding->charbuf_used; 7028 int *buf_end = buf + coding->charbuf_used;
7021 7029
7022 if (EQ (coding->src_object, coding->dst_object)) 7030 if (EQ (coding->src_object, coding->dst_object)
7031 && ! NILP (coding->dst_object))
7023 { 7032 {
7033 eassert (growable_destination (coding));
7024 coding_set_source (coding); 7034 coding_set_source (coding);
7025 dst_end = ((unsigned char *) coding->source) + coding->consumed; 7035 dst_end = ((unsigned char *) coding->source) + coding->consumed;
7026 } 7036 }
@@ -7059,6 +7069,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7059 7069
7060 if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars) 7070 if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
7061 { 7071 {
7072 eassert (growable_destination (coding));
7062 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf)) 7073 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
7063 / MAX_MULTIBYTE_LENGTH) 7074 / MAX_MULTIBYTE_LENGTH)
7064 < to_nchars) 7075 < to_nchars)
@@ -7103,7 +7114,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7103 const unsigned char *src_end = src + coding->consumed; 7114 const unsigned char *src_end = src + coding->consumed;
7104 7115
7105 if (EQ (coding->dst_object, coding->src_object)) 7116 if (EQ (coding->dst_object, coding->src_object))
7106 dst_end = (unsigned char *) src; 7117 {
7118 eassert (growable_destination (coding));
7119 dst_end = (unsigned char *) src;
7120 }
7107 if (coding->src_multibyte != coding->dst_multibyte) 7121 if (coding->src_multibyte != coding->dst_multibyte)
7108 { 7122 {
7109 if (coding->src_multibyte) 7123 if (coding->src_multibyte)
@@ -7119,6 +7133,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7119 ONE_MORE_BYTE (c); 7133 ONE_MORE_BYTE (c);
7120 if (dst == dst_end) 7134 if (dst == dst_end)
7121 { 7135 {
7136 eassert (growable_destination (coding));
7122 if (EQ (coding->src_object, coding->dst_object)) 7137 if (EQ (coding->src_object, coding->dst_object))
7123 dst_end = (unsigned char *) src; 7138 dst_end = (unsigned char *) src;
7124 if (dst == dst_end) 7139 if (dst == dst_end)
@@ -7149,6 +7164,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7149 7164
7150 if (dst >= dst_end - 1) 7165 if (dst >= dst_end - 1)
7151 { 7166 {
7167 eassert (growable_destination (coding));
7152 if (EQ (coding->src_object, coding->dst_object)) 7168 if (EQ (coding->src_object, coding->dst_object))
7153 dst_end = (unsigned char *) src; 7169 dst_end = (unsigned char *) src;
7154 if (dst >= dst_end - 1) 7170 if (dst >= dst_end - 1)
diff --git a/src/keyboard.c b/src/keyboard.c
index eef0770684e..c435ba74faa 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2355,22 +2355,15 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
2355 struct coding_system *coding 2355 struct coding_system *coding
2356 = TERMINAL_KEYBOARD_CODING (terminal); 2356 = TERMINAL_KEYBOARD_CODING (terminal);
2357 unsigned char src[MAX_ENCODED_BYTES]; 2357 unsigned char src[MAX_ENCODED_BYTES];
2358 unsigned char dest[4 * sizeof src]; 2358 unsigned char dest[MAX_ENCODED_BYTES * MAX_MULTIBYTE_LENGTH];
2359 int i; 2359 int i;
2360 for (i = 0; i < n; i++) 2360 for (i = 0; i < n; i++)
2361 src[i] = XINT (events[i]); 2361 src[i] = XINT (events[i]);
2362 if (meta_key != 2) 2362 if (meta_key != 2)
2363 for (i = 0; i < n; i++) 2363 for (i = 0; i < n; i++)
2364 src[i] &= ~0x80; 2364 src[i] &= ~0x80;
2365 2365 coding->destination = dest;
2366 /* FIXME: For some reason decode_coding_c_string requires a 2366 coding->dst_bytes = sizeof dest;
2367 fresh output buffer each time, and reusing the old buffer can
2368 make Emacs dump core. Avoid triggering the problem for now
2369 by allocating a new buffer each time through the loop. */
2370 bool please_fixme = true;
2371 coding->destination = please_fixme ? alloca (n * 4) : dest;
2372
2373 coding->dst_bytes = n * 4;
2374 decode_coding_c_string (coding, src, n, Qnil); 2367 decode_coding_c_string (coding, src, n, Qnil);
2375 eassert (coding->produced_char <= n); 2368 eassert (coding->produced_char <= n);
2376 if (coding->produced_char == 0) 2369 if (coding->produced_char == 0)