source@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: schwarze@mandoc.bsd.lv
To: source@mandoc.bsd.lv
Subject: mandoc: To prevent infinite recursion while expanding eqn(7)
Date: Wed, 13 Apr 2022 15:26:22 -0500 (EST)	[thread overview]
Message-ID: <3365015af2e83bf4@mandoc.bsd.lv> (raw)

Log Message:
-----------
To prevent infinite recursion while expanding eqn(7) definitions,
we must not reset the recursion counter when moving beyond the end
of the *previous* expansion, but we may only do so when moving
beyond the rightmost position reached by *any* expansion in the
current equation.  This matters because definitions can nest;
consider:

.EQ
define inner "content"
define outer "inner outer"
outer
.EN

This endless loop was found by tb@ using afl(1).

Incidentally, GNU eqn(1) also performs an infinite loop in this
situation and then crashes when memory runs out, but that's not an
excuse for nasty behaviour of mandoc(1).

While here, consistently print the expanded content even when the
expansion is finally truncated.  While that is not likely to help
end-users, it may help authors of eqn(7) code to understand what's
going on.  Besides, it sends a very clear signal that something is
amiss, which was easy to miss in the past unless people
enabled -W error or used -T lint.

Modified Files:
--------------
    mandoc:
        eqn_parse.h
        eqn.c
    mandoc/regress/eqn/define:
        infinite.in
        infinite.out_ascii
        infinite.out_lint

Revision Data
-------------
Index: eqn_parse.h
===================================================================
RCS file: /home/cvs/mandoc/mandoc/eqn_parse.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -Leqn_parse.h -Leqn_parse.h -u -p -r1.3 -r1.4
--- eqn_parse.h
+++ eqn_parse.h
@@ -1,7 +1,7 @@
-/*	$Id$ */
+/* $Id$ */
 /*
+ * Copyright (c) 2014, 2017, 2018, 2022 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -32,6 +32,8 @@ struct	eqn_node {
 	size_t		  defsz;   /* Number of definitions. */
 	size_t		  sz;      /* Length of the source code. */
 	size_t		  toksz;   /* Length of the current token. */
+	int		  sublen;  /* End of rightmost substitution, so far. */
+	int		  subcnt;  /* Number of recursive substitutions. */
 	int		  gsize;   /* Default point size. */
 	int		  delim;   /* In-line delimiters enabled. */
 	char		  odelim;  /* In-line opening delimiter. */
Index: eqn.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/eqn.c,v
retrieving revision 1.84
retrieving revision 1.85
diff -Leqn.c -Leqn.c -u -p -r1.84 -r1.85
--- eqn.c
+++ eqn.c
@@ -1,7 +1,8 @@
-/*	$Id$ */
+/* $Id$ */
 /*
+ * Copyright (c) 2014, 2015, 2017, 2018, 2020, 2022
+ *               Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014,2015,2017,2018,2020 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -375,19 +376,17 @@ eqn_def_find(struct eqn_node *ep)
 static enum eqn_tok
 eqn_next(struct eqn_node *ep, enum parse_mode mode)
 {
-	static int	 last_len, lim;
-
 	struct eqn_def	*def;
 	size_t		 start;
-	int		 diff, i, quoted;
+	int		 diff, i, newlen, quoted;
 	enum eqn_tok	 tok;
 
 	/*
 	 * Reset the recursion counter after advancing
-	 * beyond the end of the previous substitution.
+	 * beyond the end of the rightmost substitution.
 	 */
-	if (ep->end - ep->data >= last_len)
-		lim = 0;
+	if (ep->end - ep->data >= ep->sublen)
+		ep->subcnt = 0;
 
 	ep->start = ep->end;
 	quoted = mode == MODE_QUOTED;
@@ -434,10 +433,10 @@ eqn_next(struct eqn_node *ep, enum parse
 			return EQN_TOK__MAX;
 		if ((def = eqn_def_find(ep)) == NULL)
 			break;
-		if (++lim > EQN_NEST_MAX) {
+		if (++ep->subcnt > EQN_NEST_MAX) {
 			mandoc_msg(MANDOCERR_ROFFLOOP,
 			    ep->node->line, ep->node->pos, NULL);
-			return EQN_TOK_EOF;
+			break;
 		}
 
 		/* Replace a defined name with its string value. */
@@ -446,12 +445,15 @@ eqn_next(struct eqn_node *ep, enum parse
 			ep->sz += diff;
 			ep->data = mandoc_realloc(ep->data, ep->sz + 1);
 			ep->start = ep->data + start;
+			ep->sublen += diff;
 		}
 		if (diff)
 			memmove(ep->start + def->valsz, ep->start + ep->toksz,
 			    strlen(ep->start + ep->toksz) + 1);
 		memcpy(ep->start, def->val, def->valsz);
-		last_len = ep->start - ep->data + def->valsz;
+		newlen = ep->start - ep->data + def->valsz;
+		if (ep->sublen < newlen)
+			ep->sublen = newlen;
 	}
 	if (mode != MODE_TOK)
 		return quoted ? EQN_TOK_QUOTED : EQN_TOK__MAX;
@@ -678,6 +680,8 @@ eqn_parse(struct eqn_node *ep)
 		return;
 
 	ep->start = ep->end = ep->data;
+	ep->sublen = 0;
+	ep->subcnt = 0;
 
 next_tok:
 	tok = eqn_next(ep, MODE_TOK);
Index: infinite.out_ascii
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/eqn/define/infinite.out_ascii,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lregress/eqn/define/infinite.out_ascii -Lregress/eqn/define/infinite.out_ascii -u -p -r1.2 -r1.3
--- regress/eqn/define/infinite.out_ascii
+++ regress/eqn/define/infinite.out_ascii
@@ -4,12 +4,72 @@ N\bNA\bAM\bME\bE
      d\bde\bef\bfi\bin\bne\be-\b-i\bin\bnf\bfi\bin\bni\bit\bte\be - infinite recursion in define statements
 
 D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
-     alone: eol
+     alone: _\bk_\be_\by eol
 
-     leading position: eol
+     leading position: _\bk_\be_\by _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx eol
 
-     middle position: eol
+     middle position: _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bk_\be_\by
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx
+     _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx _\bs_\bu_\bf_\bf_\bi_\bx eol
 
-     trailing position: eol
+     trailing position: _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx _\bp_\br_\be_\bf_\bi_\bx
+     _\bp_\br_\be_\bf_\bi_\bx _\bk_\be_\by eol
 
-OpenBSD                          July 4, 2017                          OpenBSD
+     nested expansion: _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt
+     _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bc_\bo_\bn_\bt_\be_\bn_\bt _\bo_\bu_\bt_\be_\br eol
+
+OpenBSD                         April 13, 2022                         OpenBSD
Index: infinite.out_lint
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/eqn/define/infinite.out_lint,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lregress/eqn/define/infinite.out_lint -Lregress/eqn/define/infinite.out_lint -u -p -r1.6 -r1.7
--- regress/eqn/define/infinite.out_lint
+++ regress/eqn/define/infinite.out_lint
@@ -2,3 +2,4 @@ mandoc: infinite.in:10:2: ERROR: input s
 mandoc: infinite.in:16:2: ERROR: input stack limit exceeded, infinite loop?
 mandoc: infinite.in:22:2: ERROR: input stack limit exceeded, infinite loop?
 mandoc: infinite.in:28:2: ERROR: input stack limit exceeded, infinite loop?
+mandoc: infinite.in:34:2: ERROR: input stack limit exceeded, infinite loop?
Index: infinite.in
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/eqn/define/infinite.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lregress/eqn/define/infinite.in -Lregress/eqn/define/infinite.in -u -p -r1.2 -r1.3
--- regress/eqn/define/infinite.in
+++ regress/eqn/define/infinite.in
@@ -1,4 +1,4 @@
-.\" $OpenBSD: infinite.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $
+.\" $OpenBSD: infinite.in,v 1.3 2022/04/13 20:19:18 schwarze Exp $
 .Dd $Mdocdate$
 .Dt DEFINE-INFINITE 1
 .Os
@@ -27,5 +27,13 @@ eol
 trailing position:
 .EQ
 define key 'prefix key' key
+.EN
+eol
+.Pp
+nested expansion:
+.EQ
+define inner "content"
+define outer "inner outer"
+outer
 .EN
 eol
--
 To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv


                 reply	other threads:[~2022-04-13 20:26 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3365015af2e83bf4@mandoc.bsd.lv \
    --to=schwarze@mandoc.bsd.lv \
    --cc=source@mandoc.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).