aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/main.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2010-12-10 20:58:56 +0000
committerIngo Schwarze <schwarze@openbsd.org>2010-12-10 20:58:56 +0000
commit81689ffd1549a3846ce2cda5142974f268795426 (patch)
tree6f8b0f3cae35bd5cb71058ee27a6ad21750b52c3 /main.c
parent7642cc3b7f2a5238132e168211d75b0d999161b6 (diff)
downloadmandoc-81689ffd1549a3846ce2cda5142974f268795426.tar.gz
mandoc-81689ffd1549a3846ce2cda5142974f268795426.tar.zst
mandoc-81689ffd1549a3846ce2cda5142974f268795426.zip
Abort endless loops during roff macro and string expansion.
For now, use the simplest conceivable approach, like groff does: Just a fixed, ugly input stack limit. "check it in" kristaps@
Diffstat (limited to 'main.c')
-rw-r--r--main.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/main.c b/main.c
index 5468bbc7..89bd4ef8 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.121 2010/12/06 16:55:35 kristaps Exp $ */
+/* $Id: main.c,v 1.122 2010/12/10 20:58:56 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -41,6 +41,7 @@
#define MAP_FILE 0
#endif
+#define REPARSE_LIMIT 1000
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
/* FIXME: Intel's compiler? LLVM? pcc? */
@@ -89,6 +90,7 @@ struct curparse {
struct mdoc *mdoc; /* mdoc parser */
struct roff *roff; /* roff parser (!NULL) */
struct regset regs; /* roff registers */
+ int reparse_count; /* finite interpolation stack */
enum outt outtype; /* which output to use */
out_mdoc outmdoc; /* mdoc output ptr */
out_man outman; /* man output ptr */
@@ -177,6 +179,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"generic error",
+ "input stack limit exceeded, infinite loop?",
"skipping bad character",
"skipping text before the first section header",
"skipping unknown macro",
@@ -665,8 +668,10 @@ parsebuf(struct curparse *curp, struct buf blk, int start)
if (0 == pos && '\0' == blk.buf[i])
break;
- if (start)
+ if (start) {
curp->line = lnn;
+ curp->reparse_count = 0;
+ }
while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {
if ('\n' == blk.buf[i]) {
@@ -765,7 +770,11 @@ rerun:
switch (rr) {
case (ROFF_REPARSE):
- parsebuf(curp, ln, 0);
+ if (REPARSE_LIMIT >= ++curp->reparse_count)
+ parsebuf(curp, ln, 0);
+ else
+ mmsg(MANDOCERR_ROFFLOOP, curp,
+ curp->line, pos, NULL);
pos = 0;
continue;
case (ROFF_APPEND):