diff options
author | 2013-12-18 00:37:59 +0000 | |
---|---|---|
committer | 2013-12-18 00:37:59 +0000 | |
commit | 8d2bd14bc4b8b892b7002f8103dd519957ebea2d (patch) | |
tree | cd86a2c66297a6efd68c2fe4b16e1689e885d326 | |
parent | mention mac address being in lowercase hex (diff) | |
download | wireguard-openbsd-8d2bd14bc4b8b892b7002f8103dd519957ebea2d.tar.xz wireguard-openbsd-8d2bd14bc4b8b892b7002f8103dd519957ebea2d.zip |
Code existed to print non-printable characters in strings written
to the leases file. No code existed to correctly read back the
strings so written.
Redo both sides and use vis()/strnunvis() instead of handrolling
more parsing. As a side-effect allow embedded NUL characters rather
than skipping them.
-rw-r--r-- | sbin/dhclient/conflex.c | 32 | ||||
-rw-r--r-- | sbin/dhclient/options.c | 21 |
2 files changed, 31 insertions, 22 deletions
diff --git a/sbin/dhclient/conflex.c b/sbin/dhclient/conflex.c index 5cccce5098d..9eedf051dd4 100644 --- a/sbin/dhclient/conflex.c +++ b/sbin/dhclient/conflex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conflex.c,v 1.25 2013/12/05 22:31:35 krw Exp $ */ +/* $OpenBSD: conflex.c,v 1.26 2013/12/18 00:37:59 krw Exp $ */ /* Lexical scanner for dhclient config file. */ @@ -43,6 +43,8 @@ #include "dhcpd.h" #include "dhctoken.h" +#include <vis.h> + int lexline; int lexchar; char *token_line; @@ -60,6 +62,7 @@ static int token; static int ugflag; static char *tval; static char tokbuf[1500]; +static char visbuf[1500]; static int get_char(FILE *); static int get_token(FILE *); @@ -235,25 +238,34 @@ read_string(FILE *cfile) { int i, c, bs; + /* + * Read in characters until an un-escaped '"' is encountered. And + * then unvis the data that was read. + */ bs = i = 0; - do { - c = get_char(cfile); + memset(visbuf, 0, sizeof(visbuf)); + while ((c = get_char(cfile)) != EOF) { + if (c == '"' && bs == 0) + break; + + visbuf[i++] = c; if (bs) bs = 0; else if (c == '\\') bs = 1; - if (c != '"' && c != EOF && bs == 0) - tokbuf[i++] = c; - - } while (i < (sizeof(tokbuf) - 1) && c != EOF && c != '"'); + if (i == sizeof(visbuf) - 1) + break; + } + if (bs == 1) + visbuf[--i] = '\0'; + i = strnunvis(tokbuf, visbuf, sizeof(tokbuf)); if (c == EOF) parse_warn("eof in string constant"); - else if (c != '"') - parse_warn("string constant larger than internal buffer"); + else if (i == -1 || i >= sizeof(tokbuf)) + parse_warn("string constant too long"); - tokbuf[i] = 0; tval = tokbuf; return (TOK_STRING); diff --git a/sbin/dhclient/options.c b/sbin/dhclient/options.c index b105f298bb7..59b0c2b4aed 100644 --- a/sbin/dhclient/options.c +++ b/sbin/dhclient/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.60 2013/12/14 16:06:42 krw Exp $ */ +/* $OpenBSD: options.c,v 1.61 2013/12/18 00:37:59 krw Exp $ */ /* DHCP options parsing and reassembly. */ @@ -42,6 +42,8 @@ #include "dhcpd.h" +#include <vis.h> + int parse_option_buffer(struct option_data *, unsigned char *, int); /* @@ -197,7 +199,7 @@ pretty_print_option(unsigned int code, struct option_data *option, { static char optbuf[32768]; /* XXX */ int hunksize = 0, numhunk = -1, numelem = 0; - char fmtbuf[32], *op = optbuf; + char fmtbuf[32], visbuf[5], *op = optbuf; int i, j, k, opleft = sizeof(optbuf); unsigned char *data = option->data; unsigned char *dp = data; @@ -327,19 +329,14 @@ pretty_print_option(unsigned int code, struct option_data *option, op += opcount; } for (; dp < data + len; dp++) { - if (!isascii(*dp) || !isprint(*dp)) { - opcount = snprintf(op, opleft, - "\\%03o", *dp); - } else if (*dp == '"' || - *dp == '\'' || - *dp == '$' || - *dp == '`' || - *dp == '\\') { + if (*dp && strchr("\"'$`\\", *dp)) opcount = snprintf(op, opleft, "\\%c", *dp); - } else { + else { + vis(visbuf, *dp, VIS_OCTAL, + *dp+1); opcount = snprintf(op, opleft, - "%c", *dp); + "%s", visbuf); } if (opcount >= opleft || opcount == -1) goto toobig; |