Author: pfg
Date: Tue Nov 24 04:15:13 2015
New Revision: 291234
URL: https://svnweb.freebsd.org/changeset/base/291234

Log:
  bc(1): Fix memory corruption issues
  
  Fix crashes and hangs found by AFL.
  Improve handling of non-ascii chars.
  
  Obtained from:        OpenBSD (CVS rev 1.49)

Modified:
  head/usr.bin/bc/bc.y

Modified: head/usr.bin/bc/bc.y
==============================================================================
--- head/usr.bin/bc/bc.y        Tue Nov 24 03:42:58 2015        (r291233)
+++ head/usr.bin/bc/bc.y        Tue Nov 24 04:15:13 2015        (r291234)
@@ -80,7 +80,7 @@ static void            grow(void);
 static ssize_t          cs(const char *);
 static ssize_t          as(const char *);
 static ssize_t          node(ssize_t, ...);
-static void             emit(ssize_t);
+static void             emit(ssize_t, int);
 static void             emit_macro(int, ssize_t);
 static void             free_tree(void);
 static ssize_t          numnode(int);
@@ -196,7 +196,7 @@ program             : /* empty */
 
 input_item     : semicolon_list NEWLINE
                        {
-                               emit($1);
+                               emit($1, 0);
                                macro_char = reset_macro_char;
                                putchar('\n');
                                free_tree();
@@ -826,13 +826,18 @@ node(ssize_t arg, ...)
 }
 
 static void
-emit(ssize_t i)
+emit(ssize_t i, int level)
 {
 
-       if (instructions[i].index >= 0)
-               while (instructions[i].index != END_NODE)
-                       emit(instructions[i++].index);
-       else
+       if (level > 1000)
+               errx(1, "internal error: tree level > 1000");
+       if (instructions[i].index >= 0) {
+               while (instructions[i].index != END_NODE &&
+                   instructions[i].index != i)  {
+                       emit(instructions[i].index, level + 1);
+                       i++;
+               }
+       } else if (instructions[i].index != END_NODE)
                fputs(instructions[i].u.cstr, stdout);
 }
 
@@ -841,7 +846,7 @@ emit_macro(int nodeidx, ssize_t code)
 {
 
        putchar('[');
-       emit(code);
+       emit(code, 0);
        printf("]s%s\n", instructions[nodeidx].u.cstr);
        nesting--;
 }
@@ -978,7 +983,7 @@ yyerror(const char *s)
            !isprint((unsigned char)yytext[0]))
                n = asprintf(&str,
                    "%s: %s:%d: %s: ascii char 0x%02x unexpected",
-                   __progname, filename, lineno, s, yytext[0]);
+                   __progname, filename, lineno, s, yytext[0] & 0xff);
        else
                n = asprintf(&str, "%s: %s:%d: %s: %s unexpected",
                    __progname, filename, lineno, s, yytext);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to