]> code.delx.au - gnu-emacs/commitdiff
Fix unlikely core dump in init_tty, and simplify terminfo case.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 26 Aug 2013 18:10:30 +0000 (11:10 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 26 Aug 2013 18:10:30 +0000 (11:10 -0700)
* 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.

src/ChangeLog
src/term.c
src/termchar.h

index 324fa156f688b140fdf81433c7d77b4bcafbb1fc..5fd090f4b2df587cff8fee1fd9f14e7c7c08d92a 100644 (file)
@@ -1,5 +1,17 @@
 2013-08-26  Paul Eggert  <eggert@cs.ucla.edu>
 
+       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.
+
        * frame.c (check_minibuf_window): Initialize 'window' properly,
        so that Emacs reliably aborts later if 'window' is not initialized.
 
index 2966466aed216ee1004571b3a61fda16a9464f2e..aa61fde06ee585dc95219c8014272406a7da9ec2 100644 (file)
@@ -2934,9 +2934,12 @@ dissociate_if_controlling_tty (int fd)
 struct terminal *
 init_tty (const char *name, const char *terminal_type, bool must_succeed)
 {
-  char *area = NULL;
+#ifdef TERMINFO
+  char **address = 0;
+#else
+  char *area;
   char **address = &area;
-  int buffer_size = 4096;
+#endif
   int status;
   struct tty_display_info *tty = NULL;
   struct terminal *terminal = NULL;
@@ -3024,12 +3027,16 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
 
   Wcm_clear (tty);
 
-  tty->termcap_term_buffer = xmalloc (buffer_size);
-
   /* On some systems, tgetent tries to access the controlling
      terminal.  */
   block_tty_out_signal ();
+#ifdef TERMINFO
+  status = tgetent (0, terminal_type);
+#else
   status = tgetent (tty->termcap_term_buffer, terminal_type);
+  if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1])
+    emacs_abort ();
+#endif
   unblock_tty_out_signal ();
 
   if (status < 0)
@@ -3061,11 +3068,8 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
     }
 
 #ifndef TERMINFO
-  if (strlen (tty->termcap_term_buffer) >= buffer_size)
-    emacs_abort ();
-  buffer_size = strlen (tty->termcap_term_buffer);
+  area = tty->termcap_strings_buffer;
 #endif
-  tty->termcap_strings_buffer = area = xmalloc (buffer_size);
   tty->TS_ins_line = tgetstr ("al", address);
   tty->TS_ins_multi_lines = tgetstr ("AL", address);
   tty->TS_bell = tgetstr ("bl", address);
@@ -3481,9 +3485,6 @@ delete_tty (struct terminal *terminal)
 
   xfree (tty->old_tty);
   xfree (tty->Wcm);
-  xfree (tty->termcap_strings_buffer);
-  xfree (tty->termcap_term_buffer);
-
   xfree (tty);
 }
 
index 1c8e8646d4ebedd8e111f2024f826c51a8ae3499..601b9fe820588bb20f09f627bfb9f4c7079d7c6b 100644 (file)
@@ -28,6 +28,10 @@ struct tty_output
   /* There is nothing else here at the moment... */
 };
 
+#ifndef TERMINFO
+enum { TERMCAP_BUFFER_SIZE = 4096 };
+#endif
+
 /* Parameters that are shared between frames on the same tty device. */
 
 struct tty_display_info
@@ -72,14 +76,15 @@ struct tty_display_info
      mouse-face.  */
   Mouse_HLInfo mouse_highlight;
 
+#ifndef TERMINFO
   /* Buffer used internally by termcap (see tgetent in the Termcap
-     manual).  Only init_tty and delete_tty should change this.  */
-  char *termcap_term_buffer;
+     manual).  Only init_tty should use this.  */
+  char termcap_term_buffer[TERMCAP_BUFFER_SIZE];
 
   /* Buffer storing terminal description strings (see tgetstr in the
-     Termcap manual).  Only init_tty and delete_tty should change
-     this.  */
-  char *termcap_strings_buffer;
+     Termcap manual).  Only init_tty should use this.  */
+  char termcap_strings_buffer[TERMCAP_BUFFER_SIZE];
+#endif
 
   /* Strings, numbers and flags taken from the termcap entry.  */