From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 22021 invoked from network); 13 Apr 2022 20:26:24 -0000 Received: from bsd.lv (HELO mandoc.bsd.lv) (66.111.2.12) by inbox.vuxu.org with ESMTPUTF8; 13 Apr 2022 20:26:24 -0000 Received: from fantadrom.bsd.lv (localhost [127.0.0.1]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id b24f1116 for ; Wed, 13 Apr 2022 15:26:22 -0500 (EST) Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id d1574795 for ; Wed, 13 Apr 2022 15:26:22 -0500 (EST) Date: Wed, 13 Apr 2022 15:26:22 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: To prevent infinite recursion while expanding eqn(7) X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <3365015af2e83bf4@mandoc.bsd.lv> 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 * Copyright (c) 2011 Kristaps Dzonsons - * Copyright (c) 2014, 2017, 2018 Ingo Schwarze * * 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 * Copyright (c) 2011, 2014 Kristaps Dzonsons - * Copyright (c) 2014,2015,2017,2018,2020 Ingo Schwarze * * 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 @@ NNAAMMEE ddeeffiinnee--iinnffiinniittee - infinite recursion in define statements DDEESSCCRRIIPPTTIIOONN - alone: eol + alone: _k_e_y eol - leading position: eol + leading position: _k_e_y _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x eol - middle position: eol + middle position: _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _k_e_y + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x + _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x _s_u_f_f_i_x eol - trailing position: eol + trailing position: _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x _p_r_e_f_i_x + _p_r_e_f_i_x _k_e_y eol -OpenBSD July 4, 2017 OpenBSD + nested expansion: _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t + _c_o_n_t_e_n_t _c_o_n_t_e_n_t _c_o_n_t_e_n_t _o_u_t_e_r 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