aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-11-21 01:52:53 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-11-21 01:52:53 +0000
commit6242a9efa48427465988912bdb7e56c75b239acf (patch)
tree0ddf5283f0848a0c7880a54f9e8c00f1519a5a91 /term.c
parentb300a4ff9ca15ee75ac8b05afd9d5817390384ae (diff)
downloadmandoc-6242a9efa48427465988912bdb7e56c75b239acf.tar.gz
mandoc-6242a9efa48427465988912bdb7e56c75b239acf.tar.zst
mandoc-6242a9efa48427465988912bdb7e56c75b239acf.zip
We repeatedly observed assertion crashes in the low-level terminal
output handler because the high level terminal formatters could be tricked into setting the left margin further to the right than the right margin. Today, jsg@ found more of these with afl. Change the internal interface between both levels, aiming for simplicity and robustness of the code. Treat both margins as *independent* settings: Now, termp.offset is the requested left margin, and termp.rmargin is the available space. Let the lower level cope with that case of insufficient space. Obviously, high level code that does centering or flush right still has to do careful checks, so i did a full audit of margin settings in the terminal formatters. Fixes crashes caused by excessively long title or date strings in the man(7) footer, operating system or date strings in the mdoc(7) footer, volume strings in the man(7) or mdoc(7) header, and a few cases related to some non-prologue macros.
Diffstat (limited to 'term.c')
-rw-r--r--term.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/term.c b/term.c
index 085d254b..5b01aa68 100644
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.235 2014/11/16 21:29:35 schwarze Exp $ */
+/* $Id: term.c,v 1.236 2014/11/21 01:52:53 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -100,7 +100,7 @@ term_flushln(struct termp *p)
size_t j; /* temporary loop index for p->buf */
size_t jhy; /* last hyph before overflow w/r/t j */
size_t maxvis; /* output position of visible boundary */
- size_t mmax; /* used in calculating bp */
+ size_t rmargin; /* the rightmost of the two margins */
/*
* First, establish the maximum columns of "visible" content.
@@ -113,13 +113,17 @@ term_flushln(struct termp *p)
* is negative, it gets sign extended. Subtracting that
* very large size_t effectively adds a small number to dv.
*/
- assert (p->rmargin >= p->offset);
- dv = p->rmargin - p->offset;
+ rmargin = p->rmargin > p->offset ? p->rmargin : p->offset;
+ dv = p->rmargin - p->offset;
maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
- dv = p->maxrmargin - p->offset;
- mmax = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
- bp = TERMP_NOBREAK & p->flags ? mmax : maxvis;
+ if (p->flags & TERMP_NOBREAK) {
+ dv = p->maxrmargin > p->offset ?
+ p->maxrmargin - p->offset : 0;
+ bp = (int)dv > p->overstep ?
+ dv - (size_t)p->overstep : 0;
+ } else
+ bp = maxvis;
/*
* Calculate the required amount of padding.
@@ -188,8 +192,8 @@ term_flushln(struct termp *p)
(*p->endline)(p);
p->viscol = 0;
if (TERMP_BRIND & p->flags) {
- vbl = p->rmargin;
- vend += p->rmargin - p->offset;
+ vbl = rmargin;
+ vend += rmargin - p->offset;
} else
vbl = p->offset;