diff options
| author | Paul Eggert | 2014-09-07 15:27:59 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-09-07 15:27:59 -0700 |
| commit | 4612d1eab721a1010312382d1048c8b3a67b18fa (patch) | |
| tree | e0c89c15723fce2430853d3eddb9535ce0ad9e38 /src/coding.c | |
| parent | d5e25ad17f871ed7837fcc5277efce762c112f2a (diff) | |
| download | emacs-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/coding.c')
| -rw-r--r-- | src/coding.c | 20 |
1 files changed, 18 insertions, 2 deletions
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 | |||
| 695 | static bool | ||
| 696 | growable_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) |