summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2010-10-26 22:28:58 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2010-10-26 22:28:58 +0000
commit3d6924a8784c09d7be586e97a5b17e74976a6a58 (patch)
tree4d502a5ebef1e93c21193c232925ef5394a1c166 /usr.bin
parentfc9cda06c721bcd7f705d4d834df218f2df42688 (diff)
Support .so (low-level roff "switch source file"),
needed for Xenocara and various ports. Accept only relative paths and no ascension to the parent directory as suggested by Joerg Sonnenberger; code looked over by Joerg, too. Useful discussions with various people, among others espie@.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/mandoc/main.c38
-rw-r--r--usr.bin/mandoc/mandoc.h3
-rw-r--r--usr.bin/mandoc/roff.c26
-rw-r--r--usr.bin/mandoc/roff.h3
4 files changed, 64 insertions, 6 deletions
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c
index 9878f75f7f9..042581f20cf 100644
--- a/usr.bin/mandoc/main.c
+++ b/usr.bin/mandoc/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.51 2010/10/26 22:13:58 schwarze Exp $ */
+/* $Id: main.c,v 1.52 2010/10/26 22:28:56 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -173,6 +173,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"argument count wrong, violates syntax",
"child violates parent syntax",
"argument count wrong, violates syntax",
+ "invalid path in include directive",
"no document body",
"no document prologue",
"static buffer exhausted",
@@ -181,6 +182,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
static void pdesc(struct curparse *);
static void fdesc(struct curparse *);
static void ffile(const char *, struct curparse *);
+static int pfile(const char *, struct curparse *, int);
static int moptions(enum intt *, char *);
static int mmsg(enum mandocerr, void *,
int, int, const char *);
@@ -306,6 +308,35 @@ ffile(const char *file, struct curparse *curp)
perror(curp->file);
}
+static int
+pfile(const char *file, struct curparse *curp, int ln)
+{
+ const char *savefile;
+ int fd, savefd;
+
+ if (-1 == (fd = open(file, O_RDONLY, 0))) {
+ perror(file);
+ exit_status = MANDOCLEVEL_SYSERR;
+ return(0);
+ }
+
+ savefile = curp->file;
+ savefd = curp->fd;
+
+ curp->file = file;
+ curp->fd = fd;
+
+ pdesc(curp);
+
+ curp->file = savefile;
+ curp->fd = savefd;
+
+ if (-1 == close(fd))
+ perror(file);
+
+ return(MANDOCLEVEL_FATAL > exit_status ? 1 : 0);
+}
+
static void
resize_buf(struct buf *buf, size_t initial)
@@ -629,6 +660,11 @@ pdesc(struct curparse *curp)
} else if (ROFF_ERR == re) {
assert(MANDOCLEVEL_FATAL <= exit_status);
break;
+ } else if (ROFF_SO == re) {
+ if (pfile(ln.buf + of, curp, lnn_start))
+ continue;
+ else
+ break;
}
/*
diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h
index fbd8f057494..f063f95fac0 100644
--- a/usr.bin/mandoc/mandoc.h
+++ b/usr.bin/mandoc/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.17 2010/10/24 18:15:43 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.18 2010/10/26 22:28:57 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -114,6 +114,7 @@ enum mandocerr {
MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */
MANDOCERR_SYNTCHILD, /* child violates parent syntax */
MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */
+ MANDOCERR_SOPATH, /* invalid path in include directive */
MANDOCERR_NODOCBODY, /* no document body */
MANDOCERR_NODOCPROLOG, /* no document prologue */
MANDOCERR_MEM, /* static buffer exhausted */
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 3fe2033cb9c..8c8a84dc925 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.13 2010/09/27 21:25:28 schwarze Exp $ */
+/* $Id: roff.c,v 1.14 2010/10/26 22:28:57 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -48,11 +48,12 @@ enum rofft {
ROFF_ie,
ROFF_if,
ROFF_ig,
+ ROFF_nr,
ROFF_rm,
+ ROFF_so,
ROFF_tr,
ROFF_cblock,
ROFF_ccond, /* FIXME: remove this. */
- ROFF_nr,
ROFF_MAX
};
@@ -128,6 +129,7 @@ static int roff_res(struct roff *,
char **, size_t *, int);
static void roff_setstr(struct roff *,
const char *, const char *);
+static enum rofferr roff_so(ROFF_ARGS);
static char *roff_strdup(const char *);
/* See roff_hash_find() */
@@ -150,11 +152,12 @@ static struct roffmac roffs[ROFF_MAX] = {
{ "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
{ "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
{ "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },
+ { "nr", roff_nr, NULL, NULL, 0, NULL },
{ "rm", roff_line, NULL, NULL, 0, NULL },
+ { "so", roff_so, NULL, NULL, 0, NULL },
{ "tr", roff_line, NULL, NULL, 0, NULL },
{ ".", roff_cblock, NULL, NULL, 0, NULL },
{ "\\}", roff_ccond, NULL, NULL, 0, NULL },
- { "nr", roff_nr, NULL, NULL, 0, NULL },
};
static void roff_free1(struct roff *);
@@ -1008,6 +1011,23 @@ roff_nr(ROFF_ARGS)
}
+/* ARGSUSED */
+static enum rofferr
+roff_so(ROFF_ARGS)
+{
+ char *name;
+
+ name = *bufp + pos;
+ if ('/' == *name || strstr(name, "../") || strstr(name, "/..")) {
+ (*r->msg)(MANDOCERR_SOPATH, r->data, ln, pos, NULL);
+ return(ROFF_ERR);
+ }
+
+ *offs = pos;
+ return(ROFF_SO);
+}
+
+
static char *
roff_strdup(const char *name)
{
diff --git a/usr.bin/mandoc/roff.h b/usr.bin/mandoc/roff.h
index 728cb3a8308..9992c42126e 100644
--- a/usr.bin/mandoc/roff.h
+++ b/usr.bin/mandoc/roff.h
@@ -1,4 +1,4 @@
-/* $Id: roff.h,v 1.4 2010/08/20 00:53:35 schwarze Exp $ */
+/* $Id: roff.h,v 1.5 2010/10/26 22:28:57 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -20,6 +20,7 @@
enum rofferr {
ROFF_CONT, /* continue processing line */
ROFF_RERUN, /* re-run roff interpreter with offset */
+ ROFF_SO, /* include another file */
ROFF_IGN, /* ignore current line */
ROFF_ERR /* badness: puke and stop */
};