summaryrefslogtreecommitdiffstats
path: root/usr.bin/bc
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2015-11-24 04:15:13 +0000
committerpfg <pfg@FreeBSD.org>2015-11-24 04:15:13 +0000
commita103a63c90b032c86074552a24a369ec81689c7c (patch)
treed0dc47cd04c9afbc196f2317e3bb4f3b8d562119 /usr.bin/bc
parentdd8c453d1f25afe04aad6ae7a090f629a51c5b93 (diff)
downloadFreeBSD-src-a103a63c90b032c86074552a24a369ec81689c7c.zip
FreeBSD-src-a103a63c90b032c86074552a24a369ec81689c7c.tar.gz
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)
Diffstat (limited to 'usr.bin/bc')
-rw-r--r--usr.bin/bc/bc.y23
1 files changed, 14 insertions, 9 deletions
diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y
index 50454e6..17f308e 100644
--- a/usr.bin/bc/bc.y
+++ b/usr.bin/bc/bc.y
@@ -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);
OpenPOWER on IntegriCloud