svn commit: r291234 - head/usr.bin/bc

Pedro F. Giffuni pfg at FreeBSD.org
Tue Nov 24 04:15:14 UTC 2015


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);


More information about the svn-src-all mailing list