aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/roff.c b/roff.c
index 67319317..18b7aa65 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.169 2011/09/18 14:14:15 schwarze Exp $ */
+/* $Id: roff.c,v 1.170 2011/09/18 23:51:31 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -31,6 +31,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,
@@ -437,10 +440,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, '\\'))) {
@@ -535,7 +540,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;
}
}