From d6781dfeaa76d80d8795b239f2c7e2b729e90b64 Mon Sep 17 00:00:00 2001 From: krw Date: Mon, 3 Apr 2017 18:23:36 +0000 Subject: [PATCH] Simplify read_string() to just read the characters between the '"'s. Push the un-vising up to parse_string(). This allows both the actual string and the un-vised version to be available as desired. Use memcpy() instead of strdup() to copy un-vised string since it may legitimately contain NUL. --- sbin/dhclient/conflex.c | 18 +++++++----------- sbin/dhclient/parse.c | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/sbin/dhclient/conflex.c b/sbin/dhclient/conflex.c index 58b46ac5ac4..4200b7a70dc 100644 --- a/sbin/dhclient/conflex.c +++ b/sbin/dhclient/conflex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conflex.c,v 1.35 2017/02/12 13:15:50 krw Exp $ */ +/* $OpenBSD: conflex.c,v 1.36 2017/04/03 18:23:36 krw Exp $ */ /* Lexical scanner for dhclient config file. */ @@ -55,7 +55,6 @@ #include #include #include -#include #include "dhcp.h" #include "dhcpd.h" @@ -79,7 +78,6 @@ 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 *); @@ -248,33 +246,31 @@ 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. + * Read in characters until an un-escaped '"' is encountered. */ bs = i = 0; - memset(visbuf, 0, sizeof(visbuf)); while ((c = get_char(cfile)) != EOF) { if (c == '"' && bs == 0) break; - visbuf[i++] = c; + tokbuf[i++] = c; if (bs) bs = 0; else if (c == '\\') bs = 1; - if (i == sizeof(visbuf) - 1) + if (i == sizeof(tokbuf) - 1) break; } if (bs == 1) - visbuf[--i] = '\0'; - i = strnunvis(tokbuf, visbuf, sizeof(tokbuf)); + i--; if (c == EOF) parse_warn("eof in string constant"); - else if (i == -1 || i >= sizeof(tokbuf)) + else if (c != '"') parse_warn("string constant too long"); + tokbuf[i] = '\0'; tval = tokbuf; return (TOK_STRING); diff --git a/sbin/dhclient/parse.c b/sbin/dhclient/parse.c index d0e39fa332f..2ed73329e3a 100644 --- a/sbin/dhclient/parse.c +++ b/sbin/dhclient/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.46 2017/04/03 15:34:46 krw Exp $ */ +/* $OpenBSD: parse.c,v 1.47 2017/04/03 18:23:36 krw Exp $ */ /* Common parser code for dhcpd and dhclient. */ @@ -57,6 +57,7 @@ #include #include #include +#include #include "dhcp.h" #include "dhcpd.h" @@ -130,8 +131,9 @@ parse_semi(FILE *cfile) char * parse_string(FILE *cfile) { + static char unvisbuf[1500]; char *val, *s; - int token; + int i, token; token = next_token(&val, cfile); if (token != TOK_STRING) { @@ -140,9 +142,16 @@ parse_string(FILE *cfile) skip_to_semi(cfile); return (NULL); } - s = strdup(val); + + i = strnunvis(unvisbuf, val, sizeof(unvisbuf)); + if (i == -1) { + parse_warn("could not unvis string"); + return (NULL); + } + s = malloc(i+1); if (!s) fatalx("no memory for string %s.", val); + memcpy(s, unvisbuf, i+1); /* copy terminating NUL */ return (s); } -- 2.20.1