From d9fc4466dfe11ea393b124444b1eb4041db86b6d Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Sat, 20 Aug 2016 14:43:50 +0000 Subject: If a column list starts with implicit rows (that is, rows without .It) and roff-level nodes (e.g. tbl or eqn) follow, don't run into an assertion. Instead, wrap the roff-level nodes in their own row. Issue found by tb@ with afl(1). --- mdoc.c | 63 ++++++++++++++++++++------------------------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) (limited to 'mdoc.c') diff --git a/mdoc.c b/mdoc.c index 724d45c6..d9f0e410 100644 --- a/mdoc.c +++ b/mdoc.c @@ -1,7 +1,7 @@ -/* $Id: mdoc.c,v 1.256 2015/10/30 19:04:16 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.257 2016/08/20 14:43:50 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2012-2015 Ingo Schwarze + * Copyright (c) 2010, 2012-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 @@ -219,29 +219,19 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs) struct roff_node *n; char *c, *ws, *end; - assert(mdoc->last); n = mdoc->last; /* - * Divert directly to list processing if we're encountering a - * columnar ROFFT_BLOCK with or without a prior ROFFT_BLOCK entry - * (a ROFFT_BODY means it's already open, in which case we should - * process within its context in the normal way). + * If a column list contains plain text, assume an implicit item + * macro. This can happen one or more times at the beginning + * of such a list, intermixed with non-It mdoc macros and with + * nodes generated on the roff level, for example by tbl. */ - if (n->tok == MDOC_Bl && n->type == ROFFT_BODY && - n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) { - /* `Bl' is open without any children. */ - mdoc->flags |= MDOC_FREECOL; - mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf); - return 1; - } - - if (n->tok == MDOC_It && n->type == ROFFT_BLOCK && - NULL != n->parent && - MDOC_Bl == n->parent->tok && - LIST_column == n->parent->norm->Bl.type) { - /* `Bl' has block-level `It' children. */ + if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY && + n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) || + (n->parent != NULL && n->parent->tok == MDOC_Bl && + n->parent->norm->Bl.type == LIST_column)) { mdoc->flags |= MDOC_FREECOL; mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf); return 1; @@ -393,36 +383,23 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs) * into macro processing. */ - if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) { - mdoc_macro(mdoc, tok, ln, sv, &offs, buf); - return 1; - } - n = mdoc->last; - assert(mdoc->last); - - /* - * If the first macro of a `Bl -column', open an `It' block - * context around the parsed macro. - */ - - if (n->tok == MDOC_Bl && n->type == ROFFT_BODY && - n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) { - mdoc->flags |= MDOC_FREECOL; - mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf); + if (n == NULL || tok == MDOC_It || tok == MDOC_El) { + mdoc_macro(mdoc, tok, ln, sv, &offs, buf); return 1; } /* - * If we're following a block-level `It' within a `Bl -column' - * context (perhaps opened in the above block or in ptext()), - * then open an `It' block context around the parsed macro. + * If a column list contains a non-It macro, assume an implicit + * item macro. This can happen one or more times at the + * beginning of such a list, intermixed with text lines and + * with nodes generated on the roff level, for example by tbl. */ - if (n->tok == MDOC_It && n->type == ROFFT_BLOCK && - NULL != n->parent && - MDOC_Bl == n->parent->tok && - LIST_column == n->parent->norm->Bl.type) { + if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY && + n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) || + (n->parent != NULL && n->parent->tok == MDOC_Bl && + n->parent->norm->Bl.type == LIST_column)) { mdoc->flags |= MDOC_FREECOL; mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf); return 1; -- cgit v1.2.3-56-ge451