diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2015-01-30 00:27:10 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2015-01-30 00:27:10 +0000 |
commit | 3baae144ee3fc4330e6d84f6a382e3c7d3c1f9bd (patch) | |
tree | 2d5080cbd78df3cb351cc88d61aee00b3b5dfba5 /usr.bin/mandoc | |
parent | 94b5e59bfee0219b110324dc50b62048bd744f57 (diff) |
Make sure every layout line contains at least one cell;
fixing a NULL pointer access in term_tbl() that jsg@ found with afl.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r-- | usr.bin/mandoc/tbl_layout.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/usr.bin/mandoc/tbl_layout.c b/usr.bin/mandoc/tbl_layout.c index 407f77199af..250c00d00c4 100644 --- a/usr.bin/mandoc/tbl_layout.c +++ b/usr.bin/mandoc/tbl_layout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tbl_layout.c,v 1.21 2015/01/28 15:02:25 schwarze Exp $ */ +/* $OpenBSD: tbl_layout.c,v 1.22 2015/01/30 00:27:09 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -260,11 +260,14 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos) */ if (tbl->first_row == NULL) { + tbl->first_row = tbl->last_row = + mandoc_calloc(1, sizeof(*rp)); + } + if (tbl->first_row->first == NULL) { mandoc_msg(MANDOCERR_TBLLAYOUT_NONE, tbl->parse, ln, pos, NULL); - rp = mandoc_calloc(1, sizeof(*rp)); - cell_alloc(tbl, rp, TBL_CELL_LEFT); - tbl->first_row = tbl->last_row = rp; + cell_alloc(tbl, tbl->first_row, + TBL_CELL_LEFT); return; } @@ -280,19 +283,36 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos) rp->last->head == tbl->last_head && tbl->opts.rvert < rp->last->vert) tbl->opts.rvert = rp->last->vert; + + /* If the last line is empty, drop it. */ + + if (rp->next != NULL && + rp->next->first == NULL) { + free(rp->next); + rp->next = NULL; + } } return; default: /* Cell. */ break; } - if (rp == NULL) { /* First cell on this line. */ - rp = mandoc_calloc(1, sizeof(*rp)); - if (tbl->last_row) - tbl->last_row->next = rp; - else - tbl->first_row = rp; - tbl->last_row = rp; + /* + * If the last line had at least one cell, + * start a new one; otherwise, continue it. + */ + + if (rp == NULL) { + if (tbl->last_row == NULL || + tbl->last_row->first != NULL) { + rp = mandoc_calloc(1, sizeof(*rp)); + if (tbl->last_row) + tbl->last_row->next = rp; + else + tbl->first_row = rp; + tbl->last_row = rp; + } else + rp = tbl->last_row; } cell(tbl, rp, ln, p, &pos); } |