=================================================================== RCS file: /cvs/mandoc/eqn.c,v retrieving revision 1.82 retrieving revision 1.85 diff -u -p -r1.82 -r1.85 --- mandoc/eqn.c 2018/12/14 05:18:02 1.82 +++ mandoc/eqn.c 2022/04/13 20:26:19 1.85 @@ -1,7 +1,8 @@ -/* $Id: eqn.c,v 1.82 2018/12/14 05:18:02 schwarze Exp $ */ +/* $Id: eqn.c,v 1.85 2022/04/13 20:26:19 schwarze Exp $ */ /* + * Copyright (c) 2014, 2015, 2017, 2018, 2020, 2022 + * Ingo Schwarze * Copyright (c) 2011, 2014 Kristaps Dzonsons - * Copyright (c) 2014, 2015, 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 @@ -303,12 +304,11 @@ static void eqn_undef(struct eqn_node *); struct eqn_node * -eqn_alloc(struct mparse *parse) +eqn_alloc(void) { struct eqn_node *ep; ep = mandoc_calloc(1, sizeof(*ep)); - ep->parse = parse; ep->gsize = EQN_DEFSIZE; return ep; } @@ -376,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; @@ -400,6 +398,14 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode) case '"': quoted = 1; break; + case ' ': + case '\t': + case '~': + case '^': + if (quoted) + break; + ep->start++; + continue; default: break; } @@ -427,10 +433,10 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode) 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. */ @@ -439,12 +445,15 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode) 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; @@ -670,7 +679,9 @@ eqn_parse(struct eqn_node *ep) if (ep->data == NULL) return; - ep->start = ep->end = ep->data + strspn(ep->data, " ^~"); + ep->start = ep->end = ep->data; + ep->sublen = 0; + ep->subcnt = 0; next_tok: tok = eqn_next(ep, MODE_TOK);