diff options
author | 2015-01-28 21:10:28 +0000 | |
---|---|---|
committer | 2015-01-28 21:10:28 +0000 | |
commit | 3578e61680185ece4b85a5a14152b55c6b807ad1 (patch) | |
tree | 6626e1f4012834ed83082b51e84c1b6f3e750fb8 | |
parent | revert back to initial vnodes again so we can be sure nfs likes it (diff) | |
download | wireguard-openbsd-3578e61680185ece4b85a5a14152b55c6b807ad1.tar.xz wireguard-openbsd-3578e61680185ece4b85a5a14152b55c6b807ad1.zip |
Clean up eqn(7) error handling:
* When "define" fails, do not drop the whole equation.
* Free memory after "undef".
* Use standard mandoc error types instead of rolling our own.
* Delete obfuscating EQN_MSG() macro.
* Add function prototypes while here.
-rw-r--r-- | regress/usr.bin/mandoc/eqn/Makefile | 4 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/eqn/define/Makefile | 6 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/eqn/define/invalid.in | 36 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/eqn/define/invalid.out_ascii | 17 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/eqn/define/invalid.out_lint | 5 | ||||
-rw-r--r-- | usr.bin/mandoc/eqn.c | 125 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.h | 8 | ||||
-rw-r--r-- | usr.bin/mandoc/read.c | 8 |
8 files changed, 141 insertions, 68 deletions
diff --git a/regress/usr.bin/mandoc/eqn/Makefile b/regress/usr.bin/mandoc/eqn/Makefile index f84e16c641d..ef5effd16c0 100644 --- a/regress/usr.bin/mandoc/eqn/Makefile +++ b/regress/usr.bin/mandoc/eqn/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.1.1.1 2015/01/01 12:53:46 schwarze Exp $ +# $OpenBSD: Makefile,v 1.2 2015/01/28 21:10:28 schwarze Exp $ -SUBDIR = fromto matrix nullary over size subsup unary +SUBDIR = fromto define matrix nullary over size subsup unary .include "../Makefile.sub" .include <bsd.subdir.mk> diff --git a/regress/usr.bin/mandoc/eqn/define/Makefile b/regress/usr.bin/mandoc/eqn/define/Makefile new file mode 100644 index 00000000000..4be9cf5ebed --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/define/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2015/01/28 21:10:28 schwarze Exp $ + +REGRESS_TARGETS = invalid +LINT_TARGETS = invalid + +.include <bsd.regress.mk> diff --git a/regress/usr.bin/mandoc/eqn/define/invalid.in b/regress/usr.bin/mandoc/eqn/define/invalid.in new file mode 100644 index 00000000000..aa8bcb8c9dc --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/define/invalid.in @@ -0,0 +1,36 @@ +.Dd January 28, 2015 +.Dt DEFINE-INVALID 1 +.Os OpenBSD +.Sh NAME +.Nm define-invalid +.Nd invalid define and undef statements +.Sh DESCRIPTION +define without variable name: +.EQ +define bruch 'over' 1 bruch 2 undef bruch bruch define +.EN +eol +.Pp +define without value: +.EQ +define bruch 'over' 1 bruch 2 undef bruch bruch define bruch +.EN +eol +.Pp +define without value: +.EQ +define bruch 'over' 1 bruch 2 undef bruch bruch undef +.EN +eol +.Pp +tdefine without variable name: +.EQ +tdefine +.EN +eol +.Pp +tdefine without value: +.EQ +tdefine bruch +.EN +eol diff --git a/regress/usr.bin/mandoc/eqn/define/invalid.out_ascii b/regress/usr.bin/mandoc/eqn/define/invalid.out_ascii new file mode 100644 index 00000000000..0725dde22a3 --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/define/invalid.out_ascii @@ -0,0 +1,17 @@ +DEFINE-INVALID(1) General Commands Manual DEFINE-INVALID(1) + +NNAAMMEE + ddeeffiinnee--iinnvvaalliidd - invalid define and undef statements + +DDEESSCCRRIIPPTTIIOONN + define without variable name: 1/2 bruch eol + + define without value: 1/2 bruch eol + + define without value: 1/2 bruch eol + + tdefine without variable name: eol + + tdefine without value: eol + +OpenBSD January 28, 2015 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/define/invalid.out_lint b/regress/usr.bin/mandoc/eqn/define/invalid.out_lint new file mode 100644 index 00000000000..3f2304004dc --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/define/invalid.out_lint @@ -0,0 +1,5 @@ +mandoc: invalid.in:9:1: WARNING: skipping empty request: define +mandoc: invalid.in:15:1: WARNING: skipping empty request: define bruch +mandoc: invalid.in:21:1: WARNING: skipping empty request: undef +mandoc: invalid.in:27:1: WARNING: skipping empty request: tdefine +mandoc: invalid.in:33:1: WARNING: skipping empty request: tdefine diff --git a/usr.bin/mandoc/eqn.c b/usr.bin/mandoc/eqn.c index 3ab209c555a..ce54bd107e0 100644 --- a/usr.bin/mandoc/eqn.c +++ b/usr.bin/mandoc/eqn.c @@ -1,7 +1,7 @@ -/* $OpenBSD: eqn.c,v 1.19 2014/10/25 15:05:21 schwarze Exp $ */ +/* $OpenBSD: eqn.c,v 1.20 2015/01/28 21:10:28 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,8 +29,6 @@ #include "libmandoc.h" #include "libroff.h" -#define EQN_MSG(t, x) \ - mandoc_msg((t), (x)->parse, (x)->eqn.ln, (x)->eqn.pos, NULL) #define EQN_NEST_MAX 128 /* maximum nesting of defines */ #define STRNEQ(p1, sz1, p2, sz2) \ ((sz1) == (sz2) && 0 == strncmp((p1), (p2), (sz1))) @@ -264,6 +262,21 @@ static const struct eqnsym eqnsyms[EQNSYM__MAX] = { { ">=", ">=" }, /* EQNSYM_moreequal */ }; +static struct eqn_box *eqn_box_alloc(struct eqn_node *, struct eqn_box *); +static void eqn_box_free(struct eqn_box *); +static struct eqn_box *eqn_box_makebinary(struct eqn_node *, + enum eqn_post, struct eqn_box *); +static void eqn_def(struct eqn_node *); +static struct eqn_def *eqn_def_find(struct eqn_node *, const char *, size_t); +static void eqn_delim(struct eqn_node *); +static const char *eqn_next(struct eqn_node *, char, size_t *, int); +static const char *eqn_nextrawtok(struct eqn_node *, size_t *); +static const char *eqn_nexttok(struct eqn_node *, size_t *); +static enum rofferr eqn_parse(struct eqn_node *, struct eqn_box *); +static enum eqn_tok eqn_tok_parse(struct eqn_node *, char **); +static void eqn_undef(struct eqn_node *); + + enum rofferr eqn_read(struct eqn_node **epp, int ln, const char *p, int pos, int *offs) @@ -363,7 +376,8 @@ again: /* Prevent self-definitions. */ if (lim >= EQN_NEST_MAX) { - EQN_MSG(MANDOCERR_ROFFLOOP, ep); + mandoc_msg(MANDOCERR_ROFFLOOP, ep->parse, + ep->eqn.ln, ep->eqn.pos, NULL); return(NULL); } @@ -404,7 +418,8 @@ again: ep->cur++; } else { if (q) - EQN_MSG(MANDOCERR_ARG_QUOTE, ep); + mandoc_msg(MANDOCERR_ARG_QUOTE, ep->parse, + ep->eqn.ln, ep->eqn.pos, NULL); next = strchr(start, '\0'); *sz = (size_t)(next - start); ep->cur += *sz; @@ -598,23 +613,27 @@ eqn_delim(struct eqn_node *ep) /* * Undefine a previously-defined string. */ -static int +static void eqn_undef(struct eqn_node *ep) { const char *start; struct eqn_def *def; size_t sz; - if (NULL == (start = eqn_nextrawtok(ep, &sz))) { - EQN_MSG(MANDOCERR_EQNEOF, ep); - return(0); - } else if (NULL != (def = eqn_def_find(ep, start, sz))) - def->keysz = 0; - - return(1); + if ((start = eqn_nextrawtok(ep, &sz)) == NULL) { + mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse, + ep->eqn.ln, ep->eqn.pos, "undef"); + return; + } + if ((def = eqn_def_find(ep, start, sz)) == NULL) + return; + free(def->key); + free(def->val); + def->key = def->val = NULL; + def->keysz = def->valsz = 0; } -static int +static void eqn_def(struct eqn_node *ep) { const char *start; @@ -622,9 +641,10 @@ eqn_def(struct eqn_node *ep) struct eqn_def *def; int i; - if (NULL == (start = eqn_nextrawtok(ep, &sz))) { - EQN_MSG(MANDOCERR_EQNEOF, ep); - return(0); + if ((start = eqn_nextrawtok(ep, &sz)) == NULL) { + mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse, + ep->eqn.ln, ep->eqn.pos, "define"); + return; } /* @@ -644,47 +664,51 @@ eqn_def(struct eqn_node *ep) ep->defs[i].key = ep->defs[i].val = NULL; } - ep->defs[i].keysz = sz; - ep->defs[i].key = mandoc_realloc( - ep->defs[i].key, sz + 1); - - memcpy(ep->defs[i].key, start, sz); - ep->defs[i].key[(int)sz] = '\0'; - def = &ep->defs[i]; + def = ep->defs + i; + free(def->key); + def->key = mandoc_strndup(start, sz); + def->keysz = sz; } start = eqn_next(ep, ep->data[(int)ep->cur], &sz, 0); - - if (NULL == start) { - EQN_MSG(MANDOCERR_EQNEOF, ep); - return(-1); + if (start == NULL) { + mandoc_vmsg(MANDOCERR_REQ_EMPTY, ep->parse, + ep->eqn.ln, ep->eqn.pos, "define %s", def->key); + free(def->key); + free(def->val); + def->key = def->val = NULL; + def->keysz = def->valsz = 0; + return; } - + free(def->val); + def->val = mandoc_strndup(start, sz); def->valsz = sz; - def->val = mandoc_realloc(def->val, sz + 1); - memcpy(def->val, start, sz); - def->val[(int)sz] = '\0'; - return(1); } /* * Recursively parse an eqn(7) expression. */ -static int +static enum rofferr eqn_parse(struct eqn_node *ep, struct eqn_box *parent) { + char sym[64]; + struct eqn_box *cur; + const char *start; char *p; + size_t i, sz; enum eqn_tok tok, subtok; enum eqn_post pos; - struct eqn_box *cur; - int rc, size; - size_t i, sz; - char sym[64]; - const char *start; + int size; assert(parent != NULL); + + /* + * Empty equation. + * Do not add it to the high-level syntax tree. + */ + if (ep->data == NULL) - return(-1); + return(ROFF_IGN); next_tok: tok = eqn_tok_parse(ep, &p); @@ -692,20 +716,17 @@ next_tok: this_tok: switch (tok) { case (EQN_TOK_UNDEF): - if ((rc = eqn_undef(ep)) <= 0) - return(rc); + eqn_undef(ep); break; case (EQN_TOK_NDEFINE): case (EQN_TOK_DEFINE): - if ((rc = eqn_def(ep)) <= 0) - return(rc); + eqn_def(ep); break; case (EQN_TOK_TDEFINE): - if (NULL == eqn_nextrawtok(ep, NULL)) - EQN_MSG(MANDOCERR_EQNEOF, ep); - else if (NULL == eqn_next(ep, - ep->data[(int)ep->cur], NULL, 0)) - EQN_MSG(MANDOCERR_EQNEOF, ep); + if (eqn_nextrawtok(ep, NULL) == NULL || + eqn_next(ep, ep->data[(int)ep->cur], NULL, 0) == NULL) + mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse, + ep->eqn.ln, ep->eqn.pos, "tdefine"); break; case (EQN_TOK_DELIM): eqn_delim(ep); @@ -1035,7 +1056,7 @@ this_tok: * End of file! * TODO: make sure we're not in an open subexpression. */ - return(0); + return(ROFF_EQN); default: assert(tok == EQN_TOK__MAX); assert(NULL != p); @@ -1079,7 +1100,7 @@ eqn_end(struct eqn_node **epp) ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box)); ep->eqn.root->expectargs = UINT_MAX; - return(0 == eqn_parse(ep, ep->eqn.root) ? ROFF_EQN : ROFF_IGN); + return(eqn_parse(ep, ep->eqn.root)); } void diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 8e68d821236..a56e7578f7d 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.h,v 1.133 2015/01/28 17:30:37 schwarze Exp $ */ +/* $OpenBSD: mandoc.h,v 1.134 2015/01/28 21:10:28 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -134,12 +134,6 @@ enum mandocerr { MANDOCERR_ERROR, /* ===== start of errors ===== */ - /* related to equations */ - MANDOCERR_EQNNSCOPE, /* unexpected equation scope closure*/ - MANDOCERR_EQNSCOPE, /* equation scope open on exit */ - MANDOCERR_EQNBADSCOPE, /* overlapping equation scopes */ - MANDOCERR_EQNEOF, /* unexpected end of equation */ - /* related to tables */ MANDOCERR_TBLOPT_ALPHA, /* non-alphabetic character in tbl options */ MANDOCERR_TBLOPT_BAD, /* skipping unknown tbl option: option */ diff --git a/usr.bin/mandoc/read.c b/usr.bin/mandoc/read.c index efe7b8784bc..0fdae06fdbc 100644 --- a/usr.bin/mandoc/read.c +++ b/usr.bin/mandoc/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.94 2015/01/28 17:30:37 schwarze Exp $ */ +/* $OpenBSD: read.c,v 1.95 2015/01/28 21:10:28 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -173,12 +173,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "generic error", - /* related to equations */ - "unexpected equation scope closure", - "equation scope open on exit", - "overlapping equation scopes", - "unexpected end of equation", - /* related to tables */ "non-alphabetic character in tbl options", "skipping unknown tbl option", |