From cbfbc5190786639e07f1e30de9b06f6a7c9818f3 Mon Sep 17 00:00:00 2001 From: krw Date: Sun, 9 Jul 2017 18:45:27 +0000 Subject: [PATCH] Some parsing code cleanup: add parse_boolean(); pass literal format 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 | 62 +++++++++++++++++------------------------ sbin/dhclient/dhcpd.h | 3 +- sbin/dhclient/parse.c | 25 ++++++++++++++++- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c index afe5db7b61e..dd707782703 100644 --- a/sbin/dhclient/clparse.c +++ b/sbin/dhclient/clparse.c @@ -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 == ',') diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 45d504b706d..3c008200775 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -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 @@ -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 *); diff --git a/sbin/dhclient/parse.c b/sbin/dhclient/parse.c index a88469a0942..841841d9093 100644 --- a/sbin/dhclient/parse.c +++ b/sbin/dhclient/parse.c @@ -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) { -- 2.20.1