diff options
author | 2015-02-10 17:47:19 +0000 | |
---|---|---|
committer | 2015-02-10 17:47:19 +0000 | |
commit | d50d5b5d465299dbe231836f76358877660992a7 (patch) | |
tree | fddf6d51c1c7b99daaa1920f04afa1f14966eeb0 | |
parent | Introduce an openssl(1) certhash command. (diff) | |
download | wireguard-openbsd-d50d5b5d465299dbe231836f76358877660992a7.tar.xz wireguard-openbsd-d50d5b5d465299dbe231836f76358877660992a7.zip |
Be more careful to not generate empty .In, .St, and .Xr nodes.
That could happen when their first argument was another called macro,
causing a NULL pointer access in .St validation found by jsg@ with afl.
Make in_line_argn() easier to understand by using one state
variable rather than two.
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/St/Makefile | 12 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/St/call.in | 14 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/St/call.out_ascii | 13 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/St/call.out_lint | 1 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_macro.c | 78 |
5 files changed, 81 insertions, 37 deletions
diff --git a/regress/usr.bin/mandoc/mdoc/St/Makefile b/regress/usr.bin/mandoc/mdoc/St/Makefile index b27fcf07714..a1bde7e13af 100644 --- a/regress/usr.bin/mandoc/mdoc/St/Makefile +++ b/regress/usr.bin/mandoc/mdoc/St/Makefile @@ -1,6 +1,12 @@ -# $OpenBSD: Makefile,v 1.3 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.4 2015/02/10 17:47:19 schwarze Exp $ -REGRESS_TARGETS = badargs -LINT_TARGETS = badargs +REGRESS_TARGETS = badargs call +LINT_TARGETS = badargs call + +# groff-1.22.3 defect: +# - If the first argument of .St is the name of another macro, +# internal groff_mdoc(7) state gets corrupted. + +SKIP_GROFF = call .include <bsd.regress.mk> diff --git a/regress/usr.bin/mandoc/mdoc/St/call.in b/regress/usr.bin/mandoc/mdoc/St/call.in new file mode 100644 index 00000000000..10a45d3ad3e --- /dev/null +++ b/regress/usr.bin/mandoc/mdoc/St/call.in @@ -0,0 +1,14 @@ +.Dd February 10, 2015 +.Dt ST-CALL 1 +.Os OpenBSD +.Sh NAME +.Nm St-call +.Nd the standard macro calling other macros +.Sh STANDARDS +calling another macro: +.St Fl called +.Pp +valid argument: +.St -p1003.1-2004 +.Pp +end of file diff --git a/regress/usr.bin/mandoc/mdoc/St/call.out_ascii b/regress/usr.bin/mandoc/mdoc/St/call.out_ascii new file mode 100644 index 00000000000..17f04404851 --- /dev/null +++ b/regress/usr.bin/mandoc/mdoc/St/call.out_ascii @@ -0,0 +1,13 @@ +ST-CALL(1) General Commands Manual ST-CALL(1) + +NNAAMMEE + SStt--ccaallll - the standard macro calling other macros + +SSTTAANNDDAARRDDSS + calling another macro: --ccaalllleedd + + valid argument: IEEE Std 1003.1-2004 (``POSIX.1'') + + end of file + +OpenBSD February 10, 2015 OpenBSD diff --git a/regress/usr.bin/mandoc/mdoc/St/call.out_lint b/regress/usr.bin/mandoc/mdoc/St/call.out_lint new file mode 100644 index 00000000000..6bf60a7102b --- /dev/null +++ b/regress/usr.bin/mandoc/mdoc/St/call.out_lint @@ -0,0 +1 @@ +mandoc: call.in:9:2: WARNING: skipping empty macro: St diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c index a2fbde9f8e7..dc36316a99a 100644 --- a/usr.bin/mandoc/mdoc_macro.c +++ b/usr.bin/mandoc/mdoc_macro.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_macro.c,v 1.136 2015/02/07 16:39:44 schwarze Exp $ */ +/* $OpenBSD: mdoc_macro.c,v 1.137 2015/02/10 17:47:19 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -1283,11 +1283,12 @@ blk_part_exp(MACRO_PROT_ARGS) static void in_line_argn(MACRO_PROT_ARGS) { - int la, flushed, j, maxargs, nl; - enum margserr ac; struct mdoc_arg *arg; char *p; + enum margserr ac; enum mdoct ntok; + int state; /* arg#; -1: not yet open; -2: closed */ + int la, maxargs, nl; nl = mdoc->flags & MDOC_NEWLINE; @@ -1321,67 +1322,76 @@ in_line_argn(MACRO_PROT_ARGS) mdoc_argv(mdoc, line, tok, &arg, pos, buf); + state = -1; p = NULL; - flushed = j = 0; for (;;) { la = *pos; ac = mdoc_args(mdoc, line, pos, buf, tok, &p); + + if (ac == ARGS_WORD && state == -1 && + ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) && + mdoc_isdelim(p) == DELIM_OPEN) { + dword(mdoc, line, la, p, DELIM_OPEN, 0); + continue; + } + + if (state == -1 && tok != MDOC_In && + tok != MDOC_St && tok != MDOC_Xr) { + mdoc_elem_alloc(mdoc, line, ppos, tok, arg); + state = 0; + } + if (ac == ARGS_PUNCT || ac == ARGS_EOLN) { - if (j < 2 && tok == MDOC_Pf) + if (abs(state) < 2 && tok == MDOC_Pf) mandoc_vmsg(MANDOCERR_PF_SKIP, mdoc->parse, line, ppos, "Pf %s", p == NULL ? "at eol" : p); break; } - if ( ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) && - ac != ARGS_QWORD && j == 0 && - mdoc_isdelim(p) == DELIM_OPEN) { - dword(mdoc, line, la, p, DELIM_OPEN, 0); - continue; - } else if (j == 0) - mdoc_elem_alloc(mdoc, line, ppos, tok, arg); - - if (j == maxargs && ! flushed) { + if (state == maxargs) { rew_elem(mdoc, tok); - flushed = 1; + state = -2; } - ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && j == 0)) ? + ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && state == 0)) ? MDOC_MAX : lookup(mdoc, tok, line, la, p); if (ntok != MDOC_MAX) { - if ( ! flushed) + if (state >= 0) { rew_elem(mdoc, tok); - flushed = 1; + state = -2; + } mdoc_macro(mdoc, ntok, line, la, pos, buf); - j++; break; } - if ( ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) && - ac != ARGS_QWORD && ! flushed && - mdoc_isdelim(p) != DELIM_NONE) { + if (ac == ARGS_QWORD || + mdoc_macros[tok].flags & MDOC_IGNDELIM || + mdoc_isdelim(p) == DELIM_NONE) { + if (state == -1) { + mdoc_elem_alloc(mdoc, line, ppos, tok, arg); + state = 1; + } else if (state >= 0) + state++; + } else if (state >= 0) { rew_elem(mdoc, tok); - flushed = 1; + state = -2; } dword(mdoc, line, la, p, DELIM_MAX, MDOC_JOIN & mdoc_macros[tok].flags); - j++; } - if (j == 0) { - if (tok == MDOC_In || tok == MDOC_St || tok == MDOC_Xr) { - mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse, - line, ppos, mdoc_macronames[tok]); - return; - } - mdoc_elem_alloc(mdoc, line, ppos, tok, arg); - if (ac == ARGS_PUNCT && tok == MDOC_Pf) - append_delims(mdoc, line, pos, buf); + if (state == -1) { + mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse, + line, ppos, mdoc_macronames[tok]); + return; } - if ( ! flushed) + + if (state == 0 && tok == MDOC_Pf) + append_delims(mdoc, line, pos, buf); + if (state >= 0) rew_elem(mdoc, tok); if (nl) append_delims(mdoc, line, pos, buf); |