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 | |
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.
-rw-r--r-- | term.c | 32 | ||||
-rw-r--r-- | term.h | 8 | ||||
-rw-r--r-- | term_ascii.c | 3 | ||||
-rw-r--r-- | term_ps.c | 3 |
4 files changed, 28 insertions, 18 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++) @@ -84,7 +84,8 @@ struct termp { enum termenc enc; /* Type of encoding. */ const struct mchars *symtab; /* Character table. */ enum termfont fontl; /* Last font set. */ - enum termfont fontq[10]; /* Symmetric fonts. */ + enum termfont *fontq; /* Symmetric fonts. */ + int fontsz; /* Allocated size of font stack */ int fonti; /* Index of font stack. */ term_margin headf; /* invoked to print head */ term_margin footf; /* invoked to print foot */ @@ -127,11 +128,10 @@ size_t term_vspan(const struct termp *, size_t term_strlen(const struct termp *, const char *); size_t term_len(const struct termp *, size_t); -enum termfont term_fonttop(struct termp *); -const void *term_fontq(struct termp *); +const enum termfont *term_fontq(struct termp *); void term_fontpush(struct termp *, enum termfont); void term_fontpop(struct termp *); -void term_fontpopq(struct termp *, const void *); +void term_fontpopq(struct termp *, const enum termfont *); void term_fontrepl(struct termp *, enum termfont); void term_fontlast(struct termp *); diff --git a/term_ascii.c b/term_ascii.c index 94be3597..1231fd87 100644 --- a/term_ascii.c +++ b/term_ascii.c @@ -69,6 +69,9 @@ ascii_init(enum termenc enc, const struct mchars *mchars, char *outopts) p->symtab = mchars; p->tabwidth = 5; p->defrmargin = p->lastrmargin = 78; + p->fontq = mandoc_reallocarray(NULL, + (p->fontsz = 8), sizeof(enum termfont)); + p->fontq[0] = p->fontl = TERMFONT_NONE; p->begin = ascii_begin; p->end = ascii_end; @@ -540,6 +540,9 @@ pspdf_alloc(const struct mchars *mchars, char *outopts) p = mandoc_calloc(1, sizeof(struct termp)); p->symtab = mchars; p->enc = TERMENC_ASCII; + p->fontq = mandoc_reallocarray(NULL, + (p->fontsz = 8), sizeof(enum termfont)); + p->fontq[0] = p->fontl = TERMFONT_NONE; p->ps = mandoc_calloc(1, sizeof(struct termp_ps)); p->advance = ps_advance; |