* texi2mdoc: Prevent infinite macro expansion by incrementing a "depth" of
@ 2015-02-28 0:03 kristaps
0 siblings, 0 replies; only message in thread
From: kristaps @ 2015-02-28 0:03 UTC (permalink / raw)
To: source
Log Message:
-----------
Prevent infinite macro expansion by incrementing a "depth" of recursive
expansion IFF we're currently in a macro expansion already, where the start
of the macro expansion begins at the macro name and NOT after the name has
been parsed.
Modified Files:
--------------
texi2mdoc:
extern.h
main.c
util.c
texi2mdoc/afl:
mkdict.sh
Revision Data
-------------
Index: util.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/util.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -Lutil.c -Lutil.c -u -p -r1.16 -r1.17
--- util.c
+++ util.c
@@ -330,8 +330,11 @@ advance(struct texi *p, size_t *pos)
f->col = 0;
} else
f->col++;
- } else
+ } else {
--f->insplice;
+ if (0 == f->insplice)
+ f->depth = 0;
+ }
(*pos)++;
}
@@ -439,7 +442,7 @@ advanceto(struct texi *p, size_t *pos, s
}
static void
-texiexecmacro(struct texi *p, struct teximacro *m, size_t *pos)
+texiexecmacro(struct texi *p, struct teximacro *m, size_t sv, size_t *pos)
{
size_t valsz, realsz, aasz, asz,
ssz, i, j, k, start, end;
@@ -447,17 +450,31 @@ texiexecmacro(struct texi *p, struct tex
char **args;
const char *cp;
+ /* Disregard empty macros. */
+ if (0 == (valsz = realsz = strlen(m->value)))
+ return;
+
+ /*
+ * This is important: it protect us from macros that invoke more
+ * macros, possibly going on infinitely.
+ * We use "sv" instead of the current position because we might
+ * be invoked at the end of the macro (i.e., insplice == 0).
+ * The "sv" value was initialised at the start of the macro.
+ */
+ if (sv > 0)
+ if (++p->files[p->filepos].depth > 64)
+ texierr(p, "maximium recursive depth");
+
args = argparse(p, pos, &asz, m->argsz);
if (asz != m->argsz)
texiwarn(p, "invalid macro argument length");
aasz = asz < m->argsz ? asz : m->argsz;
if (0 == aasz) {
- texisplice(p, m->value, strlen(m->value), pos);
+ texisplice(p, m->value, valsz, pos);
return;
}
- valsz = realsz = strlen(m->value);
val = strdup(m->value);
for (i = j = 0; i < realsz; i++) {
@@ -653,7 +670,7 @@ texicmd(struct texi *p, size_t pos, size
int
parsearg(struct texi *p, size_t *pos, size_t num)
{
- size_t end;
+ size_t end, sv;
enum texicmd cmd;
struct teximacro *macro;
@@ -684,10 +701,11 @@ parsearg(struct texi *p, size_t *pos, si
continue;
}
+ sv = p->files[p->filepos - 1].insplice;
cmd = texicmd(p, *pos, &end, ¯o);
advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, pos);
+ texiexecmacro(p, macro, sv, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
@@ -703,7 +721,7 @@ parsearg(struct texi *p, size_t *pos, si
void
parsebracket(struct texi *p, size_t *pos)
{
- size_t end;
+ size_t end, sv;
enum texicmd cmd;
struct teximacro *macro;
@@ -731,10 +749,11 @@ parsebracket(struct texi *p, size_t *pos
continue;
}
+ sv = p->files[p->filepos - 1].insplice;
cmd = texicmd(p, *pos, &end, ¯o);
advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, pos);
+ texiexecmacro(p, macro, sv, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
@@ -750,7 +769,7 @@ parsebracket(struct texi *p, size_t *pos
void
parseeoln(struct texi *p, size_t *pos)
{
- size_t end;
+ size_t end, sv;
enum texicmd cmd;
struct teximacro *macro;
@@ -779,10 +798,11 @@ parseeoln(struct texi *p, size_t *pos)
continue;
}
+ sv = p->files[p->filepos - 1].insplice;
cmd = texicmd(p, *pos, &end, ¯o);
advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, pos);
+ texiexecmacro(p, macro, sv, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
@@ -800,7 +820,7 @@ parseeoln(struct texi *p, size_t *pos)
static void
parsesingle(struct texi *p, size_t *pos)
{
- size_t end;
+ size_t end, sv;
enum texicmd cmd;
struct teximacro *macro;
@@ -825,10 +845,11 @@ parsesingle(struct texi *p, size_t *pos)
return;
}
+ sv = p->files[p->filepos - 1].insplice;
cmd = texicmd(p, *pos, &end, ¯o);
advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, pos);
+ texiexecmacro(p, macro, sv, pos);
if (TEXICMD__MAX == cmd)
return;
if (NULL != texitoks[cmd].fp)
@@ -905,7 +926,7 @@ texisplice(struct texi *p, const char *b
void
parseto(struct texi *p, size_t *pos, const char *endtoken)
{
- size_t end;
+ size_t end, sv;
enum texicmd cmd;
size_t endtoksz;
struct teximacro *macro;
@@ -932,6 +953,7 @@ parseto(struct texi *p, size_t *pos, con
continue;
}
+ sv = p->files[p->filepos - 1].insplice;
cmd = texicmd(p, *pos, &end, ¯o);
advanceto(p, pos, end);
if (TEXICMD_END == cmd) {
@@ -952,7 +974,7 @@ parseto(struct texi *p, size_t *pos, con
continue;
}
if (NULL != macro)
- texiexecmacro(p, macro, pos);
+ texiexecmacro(p, macro, sv, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
@@ -1209,6 +1231,9 @@ argparse(struct texi *p, size_t *pos, si
args = NULL;
*argsz = 0;
+ if (*pos == BUFSZ(p))
+ return(args);
+
if ('{' != BUF(p)[*pos] && hint) {
/*
* Special case: if we encounter an unbracketed argument
@@ -1234,6 +1259,8 @@ argparse(struct texi *p, size_t *pos, si
return(args);
} else if ('{' != BUF(p)[*pos])
return(args);
+
+ assert('{' == BUF(p)[*pos]);
/* Parse til the closing '}', putting into the array. */
advance(p, pos);
Index: main.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/main.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -Lmain.c -Lmain.c -u -p -r1.51 -r1.52
--- main.c
+++ main.c
@@ -614,8 +614,8 @@ doignblock(struct texi *p, enum texicmd
* Thus, we keep track of scopes for matching "end" blocks.
*/
while (stack > 0 && *pos < BUFSZ(p)) {
- if (stack > 10)
- abort();
+ if (stack > 64)
+ texierr(p, "run-away nested stack?");
endt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, esz);
startt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, start, ssz);
if (NULL == endt) {
Index: extern.h
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/extern.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -Lextern.h -Lextern.h -u -p -r1.17 -r1.18
--- extern.h
+++ extern.h
@@ -317,6 +317,7 @@ struct texifile {
size_t mapsz; /* size of map */
size_t mapmaxsz; /* full size of map */
size_t insplice; /* how many bytes left in splice */
+ size_t depth; /* pasted macro recursive depth */
};
struct texi;
@@ -426,8 +427,7 @@ void parseto(struct texi *, size_t *, co
void texiabort(struct texi *, const char *)
__attribute__((noreturn));
enum texicmd
- texicmd(struct texi *, size_t,
- size_t *, struct teximacro **);
+ texicmd(struct texi *, size_t, size_t *, struct teximacro **);
void texierr(struct texi *, const char *, ...)
__attribute__((format(printf, 2, 3)))
__attribute__((noreturn));
Index: mkdict.sh
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/afl/mkdict.sh,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lafl/mkdict.sh -Lafl/mkdict.sh -u -p -r1.2 -r1.3
--- afl/mkdict.sh
+++ afl/mkdict.sh
@@ -1,6 +1,7 @@
#! /bin/sh
-rm -f dict/*
+rm -rf dict
+mkdir dict
sed -n '/TEXICMD__BEGIN/,/TEXICMD__END/p' ../main.c | \
tail -n +2 | \
--
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:[~2015-02-28 0:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-28 0:03 texi2mdoc: Prevent infinite macro expansion by incrementing a "depth" of kristaps
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).