* mdocml: Abort endless loops during roff macro and string expansion.
@ 2010-12-10 20:58 schwarze
0 siblings, 0 replies; only message in thread
From: schwarze @ 2010-12-10 20:58 UTC (permalink / raw)
To: source
Log Message:
-----------
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@
Modified Files:
--------------
mdocml:
main.c
mandoc.h
roff.7
Revision Data
-------------
Index: roff.7
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.7,v
retrieving revision 1.15
retrieving revision 1.16
diff -Lroff.7 -Lroff.7 -u -p -r1.15 -r1.16
--- roff.7
+++ roff.7
@@ -196,6 +196,12 @@ string interpolation syntax described be
.Sx ds ,
but this is rarely useful because every macro definition contains at least
one explicit newline character.
+.Pp
+In order to prevent endless recursion, both groff and
+.Xr mandoc 1
+limit the stack depth for expanding macros and strings
+to a large, but finite number.
+Do not rely on the exact value of this limit.
.Ss \&dei
Define a user-defined
.Nm
Index: mandoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -Lmandoc.h -Lmandoc.h -u -p -r1.32 -r1.33
--- mandoc.h
+++ mandoc.h
@@ -101,6 +101,7 @@ enum mandocerr {
MANDOCERR_ERROR, /* ===== start of errors ===== */
+ MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
MANDOCERR_BADCHAR, /* skipping bad character */
MANDOCERR_NOTEXT, /* skipping text before the first section header */
MANDOCERR_MACRO, /* skipping unknown macro */
Index: main.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v
retrieving revision 1.121
retrieving revision 1.122
diff -Lmain.c -Lmain.c -u -p -r1.121 -r1.122
--- main.c
+++ main.c
@@ -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[MAN
"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 b
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):
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-12-10 20:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-10 20:58 mdocml: Abort endless loops during roff macro and string expansion schwarze
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).