summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2015-01-28 21:10:28 +0000
committerschwarze <schwarze@openbsd.org>2015-01-28 21:10:28 +0000
commit3578e61680185ece4b85a5a14152b55c6b807ad1 (patch)
tree6626e1f4012834ed83082b51e84c1b6f3e750fb8
parentrevert back to initial vnodes again so we can be sure nfs likes it (diff)
downloadwireguard-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/Makefile4
-rw-r--r--regress/usr.bin/mandoc/eqn/define/Makefile6
-rw-r--r--regress/usr.bin/mandoc/eqn/define/invalid.in36
-rw-r--r--regress/usr.bin/mandoc/eqn/define/invalid.out_ascii17
-rw-r--r--regress/usr.bin/mandoc/eqn/define/invalid.out_lint5
-rw-r--r--usr.bin/mandoc/eqn.c125
-rw-r--r--usr.bin/mandoc/mandoc.h8
-rw-r--r--usr.bin/mandoc/read.c8
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",