diff options
-rw-r--r-- | usr.bin/mandoc/roff.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 5921a141785..d79c70242ba 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.42 2011/09/18 15:54:48 schwarze Exp $ */ +/* $Id: roff.c,v 1.43 2011/09/18 23:26:18 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -27,6 +27,9 @@ /* Maximum number of nested if-else conditionals. */ #define RSTACK_MAX 128 +/* Maximum number of string expansions per line, to break infinite loops. */ +#define EXPAND_LIMIT 1000 + enum rofft { ROFF_ad, ROFF_am, @@ -433,10 +436,12 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) const char *stnam; /* start of the name, after "[(*" */ const char *cp; /* end of the name, e.g. before ']' */ const char *res; /* the string to be substituted */ - int i, maxl; + int i, maxl, expand_count; size_t nsz; char *n; + expand_count = 0; + again: cp = *bufp + pos; while (NULL != (cp = strchr(cp, '\\'))) { @@ -531,7 +536,13 @@ again: *bufp = n; *szp = nsz; - goto again; + + if (EXPAND_LIMIT >= ++expand_count) + goto again; + + /* Just leave the string unexpanded. */ + mandoc_msg(MANDOCERR_ROFFLOOP, r->parse, ln, pos, NULL); + return; } } |