summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-03-08 13:18:10 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-03-08 13:18:10 +0000
commitfffc835e0eaec5783f8a4f5f0224609dff3476b7 (patch)
tree5a5bb4fd48c41e7ae604e67515aa8870a6bf84d8
parent0048f6b4d138a5084ab0895e54f81bfa74d70f76 (diff)
downloadmandoc-fffc835e0eaec5783f8a4f5f0224609dff3476b7.tar.gz
prevent infinite recursion while expanding the arguments
of a user-defined macro; issue found by tb@ with afl(1)
-rw-r--r--regress/roff/de/infinite.in6
-rw-r--r--regress/roff/de/infinite.out_ascii2
-rw-r--r--regress/roff/de/infinite.out_lint1
-rw-r--r--roff.c17
4 files changed, 23 insertions, 3 deletions
diff --git a/regress/roff/de/infinite.in b/regress/roff/de/infinite.in
index 683eba7f..b6dac1f7 100644
--- a/regress/roff/de/infinite.in
+++ b/regress/roff/de/infinite.in
@@ -7,6 +7,12 @@
.Sh DESCRIPTION
initial text
.de mym
+.Op \\$1 \\$2
+..
+.mym $1 \$1
+.mym \$1 nothing
+middle text
+.de mym
.mym
not printed
..
diff --git a/regress/roff/de/infinite.out_ascii b/regress/roff/de/infinite.out_ascii
index 7f8210ab..17070a20 100644
--- a/regress/roff/de/infinite.out_ascii
+++ b/regress/roff/de/infinite.out_ascii
@@ -4,6 +4,6 @@ NNAAMMEE
ddee--iinnffiinniittee - inifinte recursion in a user-defined macro
DDEESSCCRRIIPPTTIIOONN
- initial text final text
+ initial text [$1 $1] middle text final text
OpenBSD March 7, 2017 OpenBSD
diff --git a/regress/roff/de/infinite.out_lint b/regress/roff/de/infinite.out_lint
index 168c7be4..7cea727c 100644
--- a/regress/roff/de/infinite.out_lint
+++ b/regress/roff/de/infinite.out_lint
@@ -1 +1,2 @@
mandoc: infinite.in:13:5: ERROR: input stack limit exceeded, infinite loop?
+mandoc: infinite.in:19:5: ERROR: input stack limit exceeded, infinite loop?
diff --git a/roff.c b/roff.c
index c8f17532..54bebf78 100644
--- a/roff.c
+++ b/roff.c
@@ -3038,7 +3038,7 @@ roff_userdef(ROFF_ARGS)
{
const char *arg[9], *ap;
char *cp, *n1, *n2;
- int i, ib, ie;
+ int expand_count, i, ib, ie;
size_t asz, rsz;
/*
@@ -3062,8 +3062,9 @@ roff_userdef(ROFF_ARGS)
*/
buf->sz = strlen(r->current_string) + 1;
- n1 = cp = mandoc_malloc(buf->sz);
+ n1 = n2 = cp = mandoc_malloc(buf->sz);
memcpy(n1, r->current_string, buf->sz);
+ expand_count = 0;
while (*cp != '\0') {
/* Scan ahead for the next argument invocation. */
@@ -3083,6 +3084,18 @@ roff_userdef(ROFF_ARGS)
cp -= 2;
/*
+ * Prevent infinite recursion.
+ */
+
+ if (cp >= n2)
+ expand_count = 1;
+ else if (++expand_count > EXPAND_LIMIT) {
+ mandoc_msg(MANDOCERR_ROFFLOOP, r->parse,
+ ln, (int)(cp - n1), NULL);
+ return ROFF_IGN;
+ }
+
+ /*
* Determine the size of the expanded argument,
* taking escaping of quotes into account.
*/