Tweak tparam.c and tgoto.c.
authorTaylor R Campbell <campbell@mumble.net>
Sat, 13 Feb 2010 07:55:11 +0000 (02:55 -0500)
committerTaylor R Campbell <campbell@mumble.net>
Sat, 13 Feb 2010 07:55:11 +0000 (02:55 -0500)
(tparam.c): Use ANSI-style declarations.  Include relevant headers.
Use memcpy rather than bcopy.  Check for malloc and realloc failures.

(tterm.c): Check for tparam and tgoto failures.  Handle the case
where tparam and tgoto malloc their own memory.  Ensure that a Scheme
interrupt/GC in char_pointer_to_string does not leak that memory.

src/microcode/tparam.c
src/microcode/tterm.c

index a29a95a29f58531572248d3bb128625bebae001a..2c72be2d0b2cd5840e0b43a95680a7cfa22f78a5 100644 (file)
@@ -115,6 +115,9 @@ what you give them.   Help stamp out software-hoarding!  */
 #define NO_ARG_ARRAY
 #endif
 
+#include <stdlib.h>
+#include <string.h>
+
 extern char * tparam (char *, char *, int, int, int, int, int);
 extern char * tgoto (char *, int, int);
 
@@ -134,11 +137,8 @@ char * tparam1 (char *, char *, int, char *, char *, int *);
 
 /* VARARGS 2 */
 char *
-tparam (string, outstring, len, arg0, arg1, arg2, arg3)
-     char *string;
-     char *outstring;
-     int len;
-     int arg0, arg1, arg2, arg3;
+tparam (char *string, char *outstring, int len,
+       int arg0, int arg1, int arg2, int arg3)
 {
 #ifdef NO_ARG_ARRAY
   int arg[4];
@@ -158,9 +158,7 @@ char *UP;
 static char tgoto_buf[50];
 
 char *
-tgoto (cm, hpos, vpos)
-     char *cm;
-     int hpos, vpos;
+tgoto (char *cm, int hpos, int vpos)
 {
   int args[2];
   if (!cm)
@@ -171,12 +169,8 @@ tgoto (cm, hpos, vpos)
 }
 
 char *
-tparam1 (string, outstring, len, up, left, argp)
-     char *string;
-     char *outstring;
-     int len;
-     char *up, *left;
-     int *argp;
+tparam1 (char *string, char *outstring, int len, char *up, char *left,
+        int *argp)
 {
   int c;
   char *p = string;
@@ -200,13 +194,22 @@ tparam1 (string, outstring, len, up, left, argp)
          if (outlen == 0)
            {
              new = (char *) malloc (outlen = 40 + len);
+             if (new == 0)
+               return (0);
              outend += 40;
-             bcopy (outstring, new, op - outstring);
+             (void) memcpy (new, outstring, op - outstring);
            }
          else
            {
+             char *renew;
              outend += outlen;
-             new = (char *) realloc (outstring, outlen *= 2);
+             renew = (char *) realloc (outstring, outlen *= 2);
+             if (renew == 0)
+               {
+                 free (new);
+                 return (0);
+               }
+             new = renew;
            }
          op += new - outstring;
          outend += new - outstring;
index ec2fae30d099fdfe63f4aa05d62945f3c71cd210..81d62fb4c49b9a2c56f060563df7c7b29b3cf018 100644 (file)
@@ -76,6 +76,8 @@ static char * tputs_output_scan;
 static int
 tputs_write_char (int c)
 {
+  if (tputs_output_scan >= (tputs_output + TERMCAP_BUFFER_SIZE))
+    error_external_return ();
   (*tputs_output_scan++) = c;
   return (c);
 }
@@ -114,31 +116,73 @@ DEFINE_PRIMITIVE ("TERMCAP-GET-STRING", Prim_termcap_get_string, 1, 1, 0)
   }
 }
 
+struct tc_env
+{
+  char *string_buffer;
+  char *string_pointer;
+};
+
+static void
+protect_tc (void *environment)
+{
+  struct tc_env *env = ((struct tc_env *) environment);
+  char *pointer = (env -> string_pointer);
+  if ((pointer != 0) && (pointer != (env -> string_buffer)))
+    free (pointer);
+}
+
 DEFINE_PRIMITIVE ("TERMCAP-PARAM-STRING", Prim_termcap_param_string, 5, 5, 0)
 {
   PRIMITIVE_HEADER (5);
   {
-    char s [4096];
-    (void) tparam
-      ((STRING_ARG (1)), s, (sizeof (s)),
-       (arg_nonnegative_integer (2)),
-       (arg_nonnegative_integer (3)),
-       (arg_nonnegative_integer (4)),
-       (arg_nonnegative_integer (5)));
-    PRIMITIVE_RETURN (char_pointer_to_string (s));
+    char string_buffer [4096];
+    struct tc_env env;
+    SCHEME_OBJECT string = UNSPECIFIC;
+    (env . string_buffer) = string_buffer;
+    (env . string_pointer) = 0;
+    transaction_begin ();
+    dstack_protect ((&protect_tc), (&env));
+    (env . string_pointer)
+      = (tparam ((STRING_ARG (1)), string_buffer, (sizeof (string_buffer)),
+                (arg_nonnegative_integer (2)),
+                (arg_nonnegative_integer (3)),
+                (arg_nonnegative_integer (4)),
+                (arg_nonnegative_integer (5))));
+    if ((env . string_pointer) == 0)
+      error_external_return ();
+    string = (char_pointer_to_string (env . string_pointer));
+    transaction_commit ();
+    PRIMITIVE_RETURN (string);
   }
 }
 
+static void
+protect_free (void *environment)
+{
+  char *pointer = (* ((char **) environment));
+  if (pointer != 0)
+    free (pointer);
+}
+
 DEFINE_PRIMITIVE ("TERMCAP-GOTO-STRING", Prim_termcap_goto_string, 5, 5, 0)
 {
   PRIMITIVE_HEADER (5);
   {
+    char *string_pointer = 0;
+    SCHEME_OBJECT string = UNSPECIFIC;
     BC = (((ARG_REF (4)) == SHARP_F) ? 0 : (STRING_ARG (4)));
     UP = (((ARG_REF (5)) == SHARP_F) ? 0 : (STRING_ARG (5)));
-    PRIMITIVE_RETURN
-      (char_pointer_to_string (tgoto ((STRING_ARG (1)),
-                                     (arg_nonnegative_integer (2)),
-                                     (arg_nonnegative_integer (3)))));
+    transaction_begin ();
+    dstack_protect ((&protect_free), (&string_pointer));
+    string_pointer
+      = (tgoto ((STRING_ARG (1)),
+               (arg_nonnegative_integer (2)),
+               (arg_nonnegative_integer (3))));
+    if (string_pointer == 0)
+      error_external_return ();
+    string = (char_pointer_to_string (string_pointer));
+    transaction_commit ();
+    PRIMITIVE_RETURN (string);
   }
 }