diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-10-26 22:28:58 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-10-26 22:28:58 +0000 |
commit | 3d6924a8784c09d7be586e97a5b17e74976a6a58 (patch) | |
tree | 4d502a5ebef1e93c21193c232925ef5394a1c166 /usr.bin | |
parent | fc9cda06c721bcd7f705d4d834df218f2df42688 (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.c | 38 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.h | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 26 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.h | 3 |
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 */ }; |