diff options
| author | Paul Eggert | 2013-08-26 11:10:30 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-08-26 11:10:30 -0700 |
| commit | 1fc8eb33f5534cd3828d7cd15e95771a514dc589 (patch) | |
| tree | 93b9ac5d7ec1eda4ff3b59868e3fe9f0bae22a7f /src | |
| parent | f5adc984fbdc82def6edc297e88c3ee993c674ae (diff) | |
| download | emacs-1fc8eb33f5534cd3828d7cd15e95771a514dc589.tar.gz emacs-1fc8eb33f5534cd3828d7cd15e95771a514dc589.zip | |
Fix unlikely core dump in init_tty, and simplify terminfo case.
* term.c (init_tty) [TERMINFO]: Fix check for buffer overrun.
The old version incorrectly dumped core if malloc returned a
buffer containing only non-NUL bytes.
(init_tty): Do not allocate or free termcap buffers; the
struct does that for us now.
* termchar.h (TERMCAP_BUFFER_SIZE) [!TERMINFO]: New constant.
(struct tty_display_info): Define members termcap_term_buffer and
termcap_strings_buffer only if !TERMINFO, since terminfo doesn't
use them. Allocate them directly in struct rather than indirectly
via a pointer, to simplify init_tty.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/term.c | 23 | ||||
| -rw-r--r-- | src/termchar.h | 15 |
3 files changed, 34 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 324fa156f68..5fd090f4b2d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,17 @@ | |||
| 1 | 2013-08-26 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2013-08-26 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Fix unlikely core dump in init_tty, and simplify terminfo case. | ||
| 4 | * term.c (init_tty) [TERMINFO]: Fix check for buffer overrun. | ||
| 5 | The old version incorrectly dumped core if malloc returned a | ||
| 6 | buffer containing only non-NUL bytes. | ||
| 7 | (init_tty): Do not allocate or free termcap buffers; the | ||
| 8 | struct does that for us now. | ||
| 9 | * termchar.h (TERMCAP_BUFFER_SIZE) [!TERMINFO]: New constant. | ||
| 10 | (struct tty_display_info): Define members termcap_term_buffer and | ||
| 11 | termcap_strings_buffer only if !TERMINFO, since terminfo doesn't | ||
| 12 | use them. Allocate them directly in struct rather than indirectly | ||
| 13 | via a pointer, to simplify init_tty. | ||
| 14 | |||
| 3 | * frame.c (check_minibuf_window): Initialize 'window' properly, | 15 | * frame.c (check_minibuf_window): Initialize 'window' properly, |
| 4 | so that Emacs reliably aborts later if 'window' is not initialized. | 16 | so that Emacs reliably aborts later if 'window' is not initialized. |
| 5 | 17 | ||
diff --git a/src/term.c b/src/term.c index 2966466aed2..aa61fde06ee 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2934,9 +2934,12 @@ dissociate_if_controlling_tty (int fd) | |||
| 2934 | struct terminal * | 2934 | struct terminal * |
| 2935 | init_tty (const char *name, const char *terminal_type, bool must_succeed) | 2935 | init_tty (const char *name, const char *terminal_type, bool must_succeed) |
| 2936 | { | 2936 | { |
| 2937 | char *area = NULL; | 2937 | #ifdef TERMINFO |
| 2938 | char **address = 0; | ||
| 2939 | #else | ||
| 2940 | char *area; | ||
| 2938 | char **address = &area; | 2941 | char **address = &area; |
| 2939 | int buffer_size = 4096; | 2942 | #endif |
| 2940 | int status; | 2943 | int status; |
| 2941 | struct tty_display_info *tty = NULL; | 2944 | struct tty_display_info *tty = NULL; |
| 2942 | struct terminal *terminal = NULL; | 2945 | struct terminal *terminal = NULL; |
| @@ -3024,12 +3027,16 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) | |||
| 3024 | 3027 | ||
| 3025 | Wcm_clear (tty); | 3028 | Wcm_clear (tty); |
| 3026 | 3029 | ||
| 3027 | tty->termcap_term_buffer = xmalloc (buffer_size); | ||
| 3028 | |||
| 3029 | /* On some systems, tgetent tries to access the controlling | 3030 | /* On some systems, tgetent tries to access the controlling |
| 3030 | terminal. */ | 3031 | terminal. */ |
| 3031 | block_tty_out_signal (); | 3032 | block_tty_out_signal (); |
| 3033 | #ifdef TERMINFO | ||
| 3034 | status = tgetent (0, terminal_type); | ||
| 3035 | #else | ||
| 3032 | status = tgetent (tty->termcap_term_buffer, terminal_type); | 3036 | status = tgetent (tty->termcap_term_buffer, terminal_type); |
| 3037 | if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1]) | ||
| 3038 | emacs_abort (); | ||
| 3039 | #endif | ||
| 3033 | unblock_tty_out_signal (); | 3040 | unblock_tty_out_signal (); |
| 3034 | 3041 | ||
| 3035 | if (status < 0) | 3042 | if (status < 0) |
| @@ -3061,11 +3068,8 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ | |||
| 3061 | } | 3068 | } |
| 3062 | 3069 | ||
| 3063 | #ifndef TERMINFO | 3070 | #ifndef TERMINFO |
| 3064 | if (strlen (tty->termcap_term_buffer) >= buffer_size) | 3071 | area = tty->termcap_strings_buffer; |
| 3065 | emacs_abort (); | ||
| 3066 | buffer_size = strlen (tty->termcap_term_buffer); | ||
| 3067 | #endif | 3072 | #endif |
| 3068 | tty->termcap_strings_buffer = area = xmalloc (buffer_size); | ||
| 3069 | tty->TS_ins_line = tgetstr ("al", address); | 3073 | tty->TS_ins_line = tgetstr ("al", address); |
| 3070 | tty->TS_ins_multi_lines = tgetstr ("AL", address); | 3074 | tty->TS_ins_multi_lines = tgetstr ("AL", address); |
| 3071 | tty->TS_bell = tgetstr ("bl", address); | 3075 | tty->TS_bell = tgetstr ("bl", address); |
| @@ -3481,9 +3485,6 @@ delete_tty (struct terminal *terminal) | |||
| 3481 | 3485 | ||
| 3482 | xfree (tty->old_tty); | 3486 | xfree (tty->old_tty); |
| 3483 | xfree (tty->Wcm); | 3487 | xfree (tty->Wcm); |
| 3484 | xfree (tty->termcap_strings_buffer); | ||
| 3485 | xfree (tty->termcap_term_buffer); | ||
| 3486 | |||
| 3487 | xfree (tty); | 3488 | xfree (tty); |
| 3488 | } | 3489 | } |
| 3489 | 3490 | ||
diff --git a/src/termchar.h b/src/termchar.h index 1c8e8646d4e..601b9fe8205 100644 --- a/src/termchar.h +++ b/src/termchar.h | |||
| @@ -28,6 +28,10 @@ struct tty_output | |||
| 28 | /* There is nothing else here at the moment... */ | 28 | /* There is nothing else here at the moment... */ |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | #ifndef TERMINFO | ||
| 32 | enum { TERMCAP_BUFFER_SIZE = 4096 }; | ||
| 33 | #endif | ||
| 34 | |||
| 31 | /* Parameters that are shared between frames on the same tty device. */ | 35 | /* Parameters that are shared between frames on the same tty device. */ |
| 32 | 36 | ||
| 33 | struct tty_display_info | 37 | struct tty_display_info |
| @@ -72,14 +76,15 @@ struct tty_display_info | |||
| 72 | mouse-face. */ | 76 | mouse-face. */ |
| 73 | Mouse_HLInfo mouse_highlight; | 77 | Mouse_HLInfo mouse_highlight; |
| 74 | 78 | ||
| 79 | #ifndef TERMINFO | ||
| 75 | /* Buffer used internally by termcap (see tgetent in the Termcap | 80 | /* Buffer used internally by termcap (see tgetent in the Termcap |
| 76 | manual). Only init_tty and delete_tty should change this. */ | 81 | manual). Only init_tty should use this. */ |
| 77 | char *termcap_term_buffer; | 82 | char termcap_term_buffer[TERMCAP_BUFFER_SIZE]; |
| 78 | 83 | ||
| 79 | /* Buffer storing terminal description strings (see tgetstr in the | 84 | /* Buffer storing terminal description strings (see tgetstr in the |
| 80 | Termcap manual). Only init_tty and delete_tty should change | 85 | Termcap manual). Only init_tty should use this. */ |
| 81 | this. */ | 86 | char termcap_strings_buffer[TERMCAP_BUFFER_SIZE]; |
| 82 | char *termcap_strings_buffer; | 87 | #endif |
| 83 | 88 | ||
| 84 | /* Strings, numbers and flags taken from the termcap entry. */ | 89 | /* Strings, numbers and flags taken from the termcap entry. */ |
| 85 | 90 | ||