diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2014-12-19 17:12:04 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2014-12-19 17:12:04 +0000 |
commit | 04a689795a0d5b44eacb81cb022fc4806f18112d (patch) | |
tree | af09d99e336491cb6e6ea05052770da18d764972 /term.c | |
parent | a40eca4c1b8dab3da5f695f89a86dcad5b0692b6 (diff) | |
download | mandoc-04a689795a0d5b44eacb81cb022fc4806f18112d.tar.gz |
Enforcing an arbitrary, implementation dependent, undocumented limit
by calling assert() when valid user input exceeds it is a bad idea.
Allocate the terminal font stack dynamically instead of crashing
above 10 entries. Issue found by jsg@ with afl.
Diffstat (limited to 'term.c')
-rw-r--r-- | term.c | 32 |
1 files changed, 18 insertions, 14 deletions
@@ -43,6 +43,7 @@ term_free(struct termp *p) { free(p->buf); + free(p->fontq); free(p); } @@ -329,6 +330,7 @@ term_vspace(struct termp *p) (*p->endline)(p); } +/* Swap current and previous font; for \fP and .ft P */ void term_fontlast(struct termp *p) { @@ -339,6 +341,7 @@ term_fontlast(struct termp *p) p->fontq[p->fonti] = f; } +/* Set font, save current, discard previous; for \f, .ft, .B etc. */ void term_fontrepl(struct termp *p, enum termfont f) { @@ -347,38 +350,39 @@ term_fontrepl(struct termp *p, enum termfont f) p->fontq[p->fonti] = f; } +/* Set font, save previous. */ void term_fontpush(struct termp *p, enum termfont f) { - assert(p->fonti + 1 < 10); p->fontl = p->fontq[p->fonti]; - p->fontq[++p->fonti] = f; + if (++p->fonti == p->fontsz) { + p->fontsz += 8; + p->fontq = mandoc_reallocarray(p->fontq, + p->fontsz, sizeof(enum termfont *)); + } + p->fontq[p->fonti] = f; } -const void * +/* Retrieve pointer to current font. */ +const enum termfont * term_fontq(struct termp *p) { return(&p->fontq[p->fonti]); } -enum termfont -term_fonttop(struct termp *p) -{ - - return(p->fontq[p->fonti]); -} - +/* Flush to make the saved pointer current again. */ void -term_fontpopq(struct termp *p, const void *key) +term_fontpopq(struct termp *p, const enum termfont *key) { - while (p->fonti >= 0 && key < (void *)(p->fontq + p->fonti)) + while (p->fonti >= 0 && key < p->fontq + p->fonti) p->fonti--; assert(p->fonti >= 0); } +/* Pop one font off the stack. */ void term_fontpop(struct termp *p) { @@ -554,7 +558,7 @@ encode1(struct termp *p, int c) if (p->col + 6 >= p->maxcols) adjbuf(p, p->col + 6); - f = term_fonttop(p); + f = *term_fontq(p); if (TERMFONT_UNDER == f || TERMFONT_BI == f) { p->buf[p->col++] = '_'; @@ -586,7 +590,7 @@ encode(struct termp *p, const char *word, size_t sz) * character by character. */ - if (TERMFONT_NONE == term_fonttop(p)) { + if (*term_fontq(p) == TERMFONT_NONE) { if (p->col + sz >= p->maxcols) adjbuf(p, p->col + sz); for (i = 0; i < sz; i++) |