diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2018-12-21 17:15:18 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2018-12-21 17:15:18 +0000 |
commit | a90a19d8ea1fd9c75174c833a56f4c68dae450c4 (patch) | |
tree | 6040fbeff2ceb01c795fcdc0bf917f24038e4b44 /mdoc_argv.c | |
parent | 3cfd064738dd1ac7b31bfbb5b6eab47b4ea99b2c (diff) | |
download | mandoc-a90a19d8ea1fd9c75174c833a56f4c68dae450c4.tar.gz mandoc-a90a19d8ea1fd9c75174c833a56f4c68dae450c4.tar.zst mandoc-a90a19d8ea1fd9c75174c833a56f4c68dae450c4.zip |
Rename mandoc_getarg() to roff_getarg() and pass it the roff parser
struct as an argument such that after copy-in, it can call roff_expand()
once again, which used to be called roff_res() before this. This
fixes a subtle low-level roff(7) parsing bug reported by Fabio
Scotoni <fabio at esse dot ch> in the 4.4BSD-Lite2 mdoc.samples(7)
manual page, because that page used an escaped escape sequence in
a macro argument.
To expand escaped escape sequences in quoted mdoc(7) arguments, too,
stop bypassing the call to roff_getarg() in mdoc_argv.c, function args()
for this case. This does not solve the case of escaped escape sequences
in quoted .Bl -column phrases yet.
Because roff_expand() can make the string longer, roff_getarg() can no
longer operate in-place but needs to malloc(3) the returned string.
In the high-level parsers, free(3) that string after processing it.
Diffstat (limited to 'mdoc_argv.c')
-rw-r--r-- | mdoc_argv.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/mdoc_argv.c b/mdoc_argv.c index fc1bc699..f4ce4a87 100644 --- a/mdoc_argv.c +++ b/mdoc_argv.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_argv.c,v 1.118 2018/12/14 06:33:14 schwarze Exp $ */ +/* $Id: mdoc_argv.c,v 1.119 2018/12/21 17:15:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org> @@ -416,11 +416,8 @@ mdoc_args(struct roff_man *mdoc, int line, int *pos, char *buf, enum roff_tok tok, char **v) { struct roff_node *n; - char *v_local; enum argsflag fl; - if (v == NULL) - v = &v_local; fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok - MDOC_Dd].flags; /* @@ -448,6 +445,7 @@ args(struct roff_man *mdoc, int line, int *pos, char *buf, enum argsflag fl, char **v) { char *p; + char *v_local; int pairs; if (buf[*pos] == '\0') { @@ -459,6 +457,8 @@ args(struct roff_man *mdoc, int line, int *pos, return ARGS_EOLN; } + if (v == NULL) + v = &v_local; *v = buf + *pos; if (fl == ARGSFL_DELIM && args_checkpunct(buf, *pos)) @@ -525,13 +525,12 @@ args(struct roff_man *mdoc, int line, int *pos, * Whitespace is NOT involved in literal termination. */ - if (mdoc->flags & MDOC_PHRASELIT || buf[*pos] == '\"') { - if ( ! (mdoc->flags & MDOC_PHRASELIT)) + if (mdoc->flags & MDOC_PHRASELIT || + (mdoc->flags & MDOC_PHRASE && buf[*pos] == '\"')) { + if ((mdoc->flags & MDOC_PHRASELIT) == 0) { *v = &buf[++(*pos)]; - - if (mdoc->flags & MDOC_PHRASE) mdoc->flags |= MDOC_PHRASELIT; - + } pairs = 0; for ( ; buf[*pos]; (*pos)++) { /* Move following text left after quoted quotes. */ @@ -572,7 +571,9 @@ args(struct roff_man *mdoc, int line, int *pos, } p = &buf[*pos]; - *v = mandoc_getarg(&p, line, pos); + *v = roff_getarg(mdoc->roff, &p, line, pos); + if (v == &v_local) + free(*v); /* * After parsing the last word in this phrase, @@ -583,7 +584,7 @@ args(struct roff_man *mdoc, int line, int *pos, mdoc->flags &= ~MDOC_PHRASEQL; mdoc->flags |= MDOC_PHRASEQF; } - return ARGS_WORD; + return ARGS_ALLOC; } /* @@ -654,7 +655,9 @@ argv_multi(struct roff_man *mdoc, int line, v->value = mandoc_reallocarray(v->value, v->sz + MULTI_STEP, sizeof(char *)); - v->value[(int)v->sz] = mandoc_strdup(p); + if (ac != ARGS_ALLOC) + p = mandoc_strdup(p); + v->value[(int)v->sz] = p; } } @@ -669,7 +672,10 @@ argv_single(struct roff_man *mdoc, int line, if (ac == ARGS_EOLN) return; + if (ac != ARGS_ALLOC) + p = mandoc_strdup(p); + v->sz = 1; v->value = mandoc_malloc(sizeof(char *)); - v->value[0] = mandoc_strdup(p); + v->value[0] = p; } |