From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (fantadrom.bsd.lv [local]) by fantadrom.bsd.lv (OpenSMTPD) with ESMTPA id ac0b28f6 for ; Sat, 20 Aug 2016 13:00:04 -0500 (EST) Date: Sat, 20 Aug 2016 13:00:04 -0500 (EST) Message-Id: <6045127172042474637.enqueue@fantadrom.bsd.lv> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: When a mismatching end macro occurs while at least two nested X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- When a mismatching end macro occurs while at least two nested blocks are open, all except the innermost open block got a bogus MDOC_ENDED marker, in some situations triggering segfaults down the road which tb@ found with afl(1). Fix the logic error by figuring out up front whether an end macro has a matching body, and if it hasn't, don't mark any blocks as broken. Modified Files: -------------- mdocml: mdoc_macro.c Revision Data ------------- Index: mdoc_macro.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/mdoc_macro.c,v retrieving revision 1.208 retrieving revision 1.209 diff -Lmdoc_macro.c -Lmdoc_macro.c -u -p -r1.208 -r1.209 --- mdoc_macro.c +++ mdoc_macro.c @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2008-2012 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 @@ -549,13 +549,24 @@ blk_exp_close(MACRO_PROT_ARGS) break; } + /* Search backwards for the beginning of our own body. */ + + atok = rew_alt(tok); + body = NULL; + for (n = mdoc->last; n; n = n->parent) { + if (n->flags & MDOC_ENDED || n->tok != atok || + n->type != ROFFT_BODY || n->end != ENDBODY_NOT) + continue; + body = n; + break; + } + /* * Search backwards for beginnings of blocks, * both of our own and of pending sub-blocks. */ - atok = rew_alt(tok); - body = endbody = itblk = later = NULL; + endbody = itblk = later = NULL; for (n = mdoc->last; n; n = n->parent) { if (n->flags & MDOC_ENDED) { if ( ! (n->flags & MDOC_VALID)) @@ -563,15 +574,15 @@ blk_exp_close(MACRO_PROT_ARGS) continue; } - /* Remember the start of our own body. */ - - if (n->type == ROFFT_BODY && atok == n->tok) { - if (n->end == ENDBODY_NOT) - body = n; - continue; - } + /* + * Mismatching end macros can never break anything, + * SYNOPSIS name blocks can never be broken, + * and we only care about the breaking of BLOCKs. + */ - if (n->type != ROFFT_BLOCK || n->tok == MDOC_Nm) + if (body == NULL || + n->tok == MDOC_Nm || + n->type != ROFFT_BLOCK) continue; if (n->tok == MDOC_It) { @@ -639,8 +650,6 @@ blk_exp_close(MACRO_PROT_ARGS) if (body == NULL) { mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse, line, ppos, mdoc_macronames[tok]); - if (later != NULL) - later->flags &= ~MDOC_BROKEN; if (maxargs && endbody == NULL) { /* * Stray .Ec without previous .Eo: -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv