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)
This commit is contained in:
pfg 2015-11-24 04:15:13 +00:00
parent dd8c453d1f
commit a103a63c90

View File

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