aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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.c19
4 files changed, 24 insertions, 4 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 d91c9c2b..cf9a1baa 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.291 2017/03/03 13:55:32 schwarze Exp $ */
+/* $Id: roff.c,v 1.292 2017/03/08 13:18:10 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -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.
*/