From 6470d5413a0ebb8c5853e13667cb671eccc25ef2 Mon Sep 17 00:00:00 2001 From: schwarze Date: Wed, 10 Aug 2016 11:02:30 +0000 Subject: [PATCH] Fix assertion failures caused by whitespace inside \o'' (overstrike) sequences that jsg@ found with afl(1): * Avoid writing \t\b in term.c. * Handle trailing \b in term_ps.c. --- usr.bin/mandoc/term.c | 10 ++-- usr.bin/mandoc/term_ps.c | 104 +++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 62 deletions(-) diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c index 822872c3323..32fa1b67e7c 100644 --- a/usr.bin/mandoc/term.c +++ b/usr.bin/mandoc/term.c @@ -1,7 +1,7 @@ -/* $OpenBSD: term.c,v 1.117 2016/03/20 16:50:30 krw Exp $ */ +/* $OpenBSD: term.c,v 1.118 2016/08/10 11:02:30 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010-2015 Ingo Schwarze + * Copyright (c) 2010-2016 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -502,7 +502,9 @@ term_word(struct termp *p, const char *word) } } /* Trim trailing backspace/blank pair. */ - if (p->col > 2 && p->buf[p->col - 1] == ' ') + if (p->col > 2 && + (p->buf[p->col - 1] == ' ' || + p->buf[p->col - 1] == '\t')) p->col -= 2; continue; default: @@ -566,7 +568,7 @@ encode1(struct termp *p, int c) p->fontq[p->fonti] : TERMFONT_NONE; if (p->flags & TERMP_BACKBEFORE) { - if (p->buf[p->col - 1] == ' ') + if (p->buf[p->col - 1] == ' ' || p->buf[p->col - 1] == '\t') p->col--; else p->buf[p->col++] = 8; diff --git a/usr.bin/mandoc/term_ps.c b/usr.bin/mandoc/term_ps.c index 37a4dbde198..7aecfb72830 100644 --- a/usr.bin/mandoc/term_ps.c +++ b/usr.bin/mandoc/term_ps.c @@ -1,7 +1,7 @@ -/* $OpenBSD: term_ps.c,v 1.45 2016/07/19 13:30:16 schwarze Exp $ */ +/* $OpenBSD: term_ps.c,v 1.46 2016/08/10 11:02:30 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2014, 2015 Ingo Schwarze + * Copyright (c) 2014, 2015, 2016 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -94,10 +94,10 @@ static void ps_begin(struct termp *); static void ps_closepage(struct termp *); static void ps_end(struct termp *); static void ps_endline(struct termp *); -static void ps_fclose(struct termp *); static void ps_growbuf(struct termp *, size_t); static void ps_letter(struct termp *, int); static void ps_pclose(struct termp *); +static void ps_plast(struct termp *); static void ps_pletter(struct termp *, int); static void ps_printf(struct termp *, const char *, ...) __attribute__((__format__ (printf, 2, 3))); @@ -776,6 +776,9 @@ ps_end(struct termp *p) { size_t i, xref, base; + ps_plast(p); + ps_pclose(p); + /* * At the end of the file, do one last showpage. This is the * same behaviour as groff(1) and works for multiple pages as @@ -1019,39 +1022,53 @@ ps_pclose(struct termp *p) p->ps->flags &= ~PS_INLINE; } +/* If we have a `last' char that wasn't printed yet, print it now. */ static void -ps_fclose(struct termp *p) +ps_plast(struct termp *p) { + size_t wx; + + if (p->ps->last == '\0') + return; + + /* Check the font mode; open a new scope if it doesn't match. */ + + if (p->ps->nextf != p->ps->lastf) { + ps_pclose(p); + ps_setfont(p, p->ps->nextf); + } + p->ps->nextf = TERMFONT_NONE; /* - * Strong closure: if we have a last-char, spit it out after - * checking that we're in the right font mode. This will of - * course open a new scope, if applicable. - * - * Following this, close out any scope that's open. + * For an overstrike, if a previous character + * was wider, advance to center the new one. */ - if (p->ps->last != '\0') { - assert( ! (p->ps->flags & PS_BACKSP)); - if (p->ps->nextf != p->ps->lastf) { - ps_pclose(p); - ps_setfont(p, p->ps->nextf); - } - p->ps->nextf = TERMFONT_NONE; - ps_pletter(p, p->ps->last); - p->ps->last = '\0'; + if (p->ps->pscolnext) { + wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx; + if (p->ps->pscol + wx < p->ps->pscolnext) + p->ps->pscol = (p->ps->pscol + + p->ps->pscolnext - wx) / 2; } - if ( ! (PS_INLINE & p->ps->flags)) - return; + ps_pletter(p, p->ps->last); + p->ps->last = '\0'; - ps_pclose(p); + /* + * For an overstrike, if a previous character + * was wider, advance to the end of the old one. + */ + + if (p->ps->pscol < p->ps->pscolnext) { + ps_pclose(p); + p->ps->pscol = p->ps->pscolnext; + } } static void ps_letter(struct termp *p, int arg) { - size_t savecol, wx; + size_t savecol; char c; c = arg >= 128 || arg <= 0 ? '?' : arg; @@ -1117,43 +1134,12 @@ ps_letter(struct termp *p, int arg) * Use them and print it. */ - if (p->ps->last != '\0') { - if (p->ps->nextf != p->ps->lastf) { - ps_pclose(p); - ps_setfont(p, p->ps->nextf); - } - p->ps->nextf = TERMFONT_NONE; - - /* - * For an overstrike, if a previous character - * was wider, advance to center the new one. - */ - - if (p->ps->pscolnext) { - wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx; - if (p->ps->pscol + wx < p->ps->pscolnext) - p->ps->pscol = (p->ps->pscol + - p->ps->pscolnext - wx) / 2; - } - - ps_pletter(p, p->ps->last); - - /* - * For an overstrike, if a previous character - * was wider, advance to the end of the old one. - */ - - if (p->ps->pscol < p->ps->pscolnext) { - ps_pclose(p); - p->ps->pscol = p->ps->pscolnext; - } - } + ps_plast(p); /* * Do not print the current character yet because font - * instructions might follow; only remember it. - * For the first character, nothing else is done. - * The final character will get printed from ps_fclose(). + * instructions might follow; only remember the character. + * It will get printed later from ps_plast(). */ p->ps->last = c; @@ -1186,7 +1172,8 @@ ps_advance(struct termp *p, size_t len) * and readjust our column settings. */ - ps_fclose(p); + ps_plast(p); + ps_pclose(p); p->ps->pscol += len; } @@ -1196,7 +1183,8 @@ ps_endline(struct termp *p) /* Close out any scopes we have open: we're at eoln. */ - ps_fclose(p); + ps_plast(p); + ps_pclose(p); /* * If we're in the margin, don't try to recalculate our current -- 2.20.1