From 1b29611fc5d551d2bed6a39b9549269c02f8d24d Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 13 Feb 2010 02:55:11 -0500 Subject: [PATCH] Tweak tparam.c and tgoto.c. (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 | 35 ++++++++++++---------- src/microcode/tterm.c | 68 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/microcode/tparam.c b/src/microcode/tparam.c index a29a95a29..2c72be2d0 100644 --- a/src/microcode/tparam.c +++ b/src/microcode/tparam.c @@ -115,6 +115,9 @@ what you give them. Help stamp out software-hoarding! */ #define NO_ARG_ARRAY #endif +#include +#include + 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; diff --git a/src/microcode/tterm.c b/src/microcode/tterm.c index ec2fae30d..81d62fb4c 100644 --- a/src/microcode/tterm.c +++ b/src/microcode/tterm.c @@ -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); } } -- 2.25.1