Simplify read_string() to just read the characters between the '"'s.
authorkrw <krw@openbsd.org>
Mon, 3 Apr 2017 18:23:36 +0000 (18:23 +0000)
committerkrw <krw@openbsd.org>
Mon, 3 Apr 2017 18:23:36 +0000 (18:23 +0000)
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
sbin/dhclient/parse.c

index 58b46ac..4200b7a 100644 (file)
@@ -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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <vis.h>
 
 #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);
index d0e39fa..2ed7332 100644 (file)
@@ -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 <string.h>
 #include <syslog.h>
 #include <unistd.h>
+#include <vis.h>
 
 #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);
 }