Some parsing code cleanup: add parse_boolean(); pass literal format
authorkrw <krw@openbsd.org>
Sun, 9 Jul 2017 18:45:27 +0000 (18:45 +0000)
committerkrw <krw@openbsd.org>
Sun, 9 Jul 2017 18:45:27 +0000 (18:45 +0000)
chars to parse_decimal() instead of less obvious *fmt; refactor
to eliminate need for the 'alloc:' and 'bad_flag:' labels and the
invidious backwards goto's to them.

sbin/dhclient/clparse.c
sbin/dhclient/dhcpd.h
sbin/dhclient/parse.c

index afe5db7..dd70778 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clparse.c,v 1.119 2017/07/08 20:38:31 krw Exp $       */
+/*     $OpenBSD: clparse.c,v 1.120 2017/07/09 18:45:27 krw Exp $       */
 
 /* Parser for dhclient config and lease files. */
 
@@ -654,6 +654,7 @@ parse_option_decl(FILE *cfile, struct option_data *options)
                                if (len == -1)
                                        return (-1);
                                hunkix += len;
+                               dp = NULL;
                                break;
                        case 't': /* Text string. */
                                val = parse_string(cfile, &len);
@@ -669,24 +670,16 @@ parse_option_decl(FILE *cfile, struct option_data *options)
                                nul_term = 1;
                                hunkix += len;
                                free(val);
+                               dp = NULL;
                                break;
                        case 'I': /* IP address. */
                                if (!parse_ip_addr(cfile, &ip_addr))
                                        return (-1);
                                len = sizeof(ip_addr);
                                dp = (uint8_t *)&ip_addr;
-alloc:
-                               if (hunkix + len > sizeof(hunkbuf)) {
-                                       parse_warn("option data buffer "
-                                           "overflow");
-                                       skip_to_semi(cfile);
-                                       return (-1);
-                               }
-                               memcpy(&hunkbuf[hunkix], dp, len);
-                               hunkix += len;
                                break;
                        case 'l':       /* Signed 32-bit integer. */
-                               if (!parse_decimal(cfile, buf, *fmt)) {
+                               if (!parse_decimal(cfile, buf, 'l')) {
                                        parse_warn("expecting signed 32-bit "
                                            "integer.");
                                        skip_to_semi(cfile);
@@ -694,9 +687,9 @@ alloc:
                                }
                                len = 4;
                                dp = buf;
-                               goto alloc;
+                               break;
                        case 'L':       /* Unsigned 32-bit integer. */
-                               if (!parse_decimal(cfile, buf, *fmt)) {
+                               if (!parse_decimal(cfile, buf, 'L')) {
                                        parse_warn("expecting unsigned 32-bit "
                                            "integer.");
                                        skip_to_semi(cfile);
@@ -704,9 +697,9 @@ alloc:
                                }
                                len = 4;
                                dp = buf;
-                               goto alloc;
+                               break;
                        case 'S':       /* Unsigned 16-bit integer. */
-                               if (!parse_decimal(cfile, buf, *fmt)) {
+                               if (!parse_decimal(cfile, buf, 'S')) {
                                        parse_warn("expecting unsigned 16-bit "
                                            "integer.");
                                        skip_to_semi(cfile);
@@ -714,9 +707,9 @@ alloc:
                                }
                                len = 2;
                                dp = buf;
-                               goto alloc;
+                               break;
                        case 'B':       /* Unsigned 8-bit integer. */
-                               if (!parse_decimal(cfile, buf, *fmt)) {
+                               if (!parse_decimal(cfile, buf, 'B')) {
                                        parse_warn("expecting unsigned 8-bit "
                                            "integer.");
                                        skip_to_semi(cfile);
@@ -724,41 +717,38 @@ alloc:
                                }
                                len = 1;
                                dp = buf;
-                               goto alloc;
+                               break;
                        case 'f': /* Boolean flag. */
-                               token = next_token(&val, cfile);
-                               if (!is_identifier(token)) {
-                                       parse_warn("expecting identifier.");
-bad_flag:
-                                       if (token != ';')
-                                               skip_to_semi(cfile);
-                                       return (-1);
-                               }
-                               if (!strcasecmp(val, "true") ||
-                                   !strcasecmp(val, "on"))
-                                       buf[0] = 1;
-                               else if (!strcasecmp(val, "false") ||
-                                   !strcasecmp(val, "off"))
-                                       buf[0] = 0;
-                               else {
+                               if (!parse_boolean(cfile, buf)) {
                                        parse_warn("expecting boolean.");
-                                       goto bad_flag;
+                                       skip_to_semi(cfile);
+                                       return (-1);
                                }
                                len = 1;
                                dp = buf;
-                               goto alloc;
+                               break;
                        case 'C':
                                if (!parse_cidr(cfile, cidr))
                                        return (-1);
                                len = 1 + (cidr[0] + 7) / 8;
                                dp = cidr;
-                               goto alloc;
+                               break;
                        default:
                                log_warnx("Bad format %c in "
                                    "parse_option_param.", *fmt);
                                skip_to_semi(cfile);
                                return (-1);
                        }
+                       if (dp != NULL && len > 0) {
+                               if (hunkix + len > sizeof(hunkbuf)) {
+                                       parse_warn("option data buffer "
+                                           "overflow");
+                                       skip_to_semi(cfile);
+                                       return (-1);
+                               }
+                               memcpy(&hunkbuf[hunkix], dp, len);
+                               hunkix += len;
+                       }
                }
                token = peek_token(NULL, cfile);
                if (*fmt == 'A' && token == ',')
index 45d504b..3c00820 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.209 2017/07/08 20:38:31 krw Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.210 2017/07/09 18:45:27 krw Exp $ */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -191,6 +191,7 @@ int parse_cidr(FILE *, unsigned char *);
 void parse_lease_time(FILE *, time_t *);
 int parse_decimal(FILE *, unsigned char *, char);
 int parse_hex(FILE *, unsigned char *);
+int parse_boolean(FILE *, unsigned char *);
 time_t parse_date(FILE *);
 void parse_warn(char *);
 
index a88469a..841841d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.c,v 1.55 2017/07/08 00:36:10 krw Exp $  */
+/*     $OpenBSD: parse.c,v 1.56 2017/07/09 18:45:27 krw Exp $  */
 
 /* Common parser code for dhcpd and dhclient. */
 
@@ -245,6 +245,29 @@ parse_lease_time(FILE *cfile, time_t *timep)
        parse_semi(cfile);
 }
 
+int
+parse_boolean(FILE *cfile, unsigned char *buf)
+{
+       char    *val;
+       int      token;
+
+       token = next_token(&val, cfile);
+       if (is_identifier(token)) {
+               if (strcasecmp(val, "true") == 0 ||
+                   strcasecmp(val, "on") == 0) {
+                       buf[0] = 1;
+                       return (1);
+               }
+               if (strcasecmp(val, "false") == 0 ||
+                   strcasecmp(val, "off") == 0) {
+                       buf[0] = 0;
+                       return (1);
+               }
+       }
+
+       return (0);
+}
+
 int
 parse_decimal(FILE *cfile, unsigned char *buf, char fmt)
 {