summaryrefslogtreecommitdiffstats
path: root/eqn.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-03-11 15:43:04 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-03-11 15:43:04 +0000
commitbf4e8be28e69b65461d7a841458ac67ee3193d7f (patch)
tree860567abe8bec203a28c7c8bd01f337422e8598a /eqn.c
parent505c0b0e49d23ffdb2aad76b2d0ac3c0da6d5a54 (diff)
downloadmandoc-bf4e8be28e69b65461d7a841458ac67ee3193d7f.tar.gz
Improve detection of recursive eqn(7) "define" statements:
Do not only catch "define key 'key other stuff'", but also "define key 'other stuff key'". Fixing infinite loop found by tb@ with afl(1).
Diffstat (limited to 'eqn.c')
-rw-r--r--eqn.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/eqn.c b/eqn.c
index 2d979dcd..e3b31e98 100644
--- a/eqn.c
+++ b/eqn.c
@@ -366,15 +366,19 @@ eqn_def_find(struct eqn_node *ep, const char *key, size_t sz)
static const char *
eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
{
+ static size_t last_len;
+ static int lim;
+
char *start, *next;
- int q, diff, lim;
+ int q, diff;
size_t ssz, dummy;
struct eqn_def *def;
if (NULL == sz)
sz = &dummy;
- lim = 0;
+ if (ep->cur >= last_len)
+ lim = 0;
ep->rew = ep->cur;
again:
/* Prevent self-definitions. */
@@ -448,6 +452,7 @@ again:
memmove(start + *sz + diff, start + *sz,
(strlen(start) - *sz) + 1);
memcpy(start, def->val, def->valsz);
+ last_len = start - ep->data + def->valsz;
lim++;
goto again;
}