diff options
author | Shawn Routhier <sar@isc.org> | 2010-09-13 19:42:34 +0000 |
---|---|---|
committer | Shawn Routhier <sar@isc.org> | 2010-09-13 19:42:34 +0000 |
commit | 1a0d2b6fe81af3e183de25b0a26ab3c488c30622 (patch) | |
tree | 650ef865d11a8b46fc9aaf6e789bc8f838b80a55 | |
parent | 9313c3372d39e6590c704544a55cc33f766cdad8 (diff) | |
download | isc-dhcp-1a0d2b6fe81af3e183de25b0a26ab3c488c30622.tar.gz |
Parse date strings more properly - the code now handles semi-colons in
date strings correctly. Thanks to a patch from Jiri Popelka at Red Hat.
[ISC-Bugs #21501, #20598]
-rw-r--r-- | RELNOTES | 4 | ||||
-rw-r--r-- | common/parse.c | 186 |
2 files changed, 108 insertions, 82 deletions
@@ -135,6 +135,10 @@ suggested fixes to <dhcp-users@isc.org>. code to move most of the common code to a single routine. [ISC-Bugs #21171]. +- Parse date strings more properly - the code now handles semi-colons in + date strings correctly. Thanks to a patch from Jiri Popelka at Red Hat. + [ISC-Bugs #21501, #20598] + Changes since 4.0.2rc1 - None diff --git a/common/parse.c b/common/parse.c index c08238a3..097c6e50 100644 --- a/common/parse.c +++ b/common/parse.c @@ -848,9 +848,10 @@ void convert_num (cfile, buf, str, base, size) /* * date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER - * NUMBER COLON NUMBER COLON NUMBER SEMI | + * NUMBER COLON NUMBER COLON NUMBER | * NUMBER NUMBER SLASH NUMBER SLASH NUMBER - * NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI | + * NUMBER COLON NUMBER COLON NUMBER NUMBER | + * EPOCH NUMBER | * NEVER * * Dates are stored in UTC or with a timezone offset; first number is day @@ -859,7 +860,10 @@ void convert_num (cfile, buf, str, base, size) * optional. */ -/* just parse the date */ +/* + * just parse the date + * any trailing semi must be consumed by the caller of this routine + */ TIME parse_date_core(cfile) struct parse *cfile; @@ -868,157 +872,171 @@ parse_date_core(cfile) int tzoff, wday, year, mon, mday, hour, min, sec; const char *val; enum dhcp_token token; - static int months [11] = { 31, 59, 90, 120, 151, 181, - 212, 243, 273, 304, 334 }; + static int months[11] = { 31, 59, 90, 120, 151, 181, + 212, 243, 273, 304, 334 }; - /* Day of week, or "never"... */ - token = next_token (&val, (unsigned *)0, cfile); + /* "never", "epoch" or day of week */ + token = peek_token(&val, NULL, cfile); if (token == NEVER) { - if (!parse_semi (cfile)) - return 0; - return MAX_TIME; + token = next_token(&val, NULL, cfile); /* consume NEVER */ + return(MAX_TIME); } /* This indicates 'local' time format. */ if (token == EPOCH) { - token = next_token(&val, NULL, cfile); + token = next_token(&val, NULL, cfile); /* consume EPOCH */ + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn(cfile, "Seconds since epoch expected."); if (token != SEMI) - skip_to_semi(cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "Seconds since epoch expected."); + return((TIME)0); } + token = next_token(&val, NULL, cfile); /* consume number */ guess = atoi(val); - if (!parse_semi(cfile)) - return (TIME)0; - - return guess; + return((TIME)guess); } if (token != NUMBER) { - parse_warn (cfile, "numeric day of week expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric day of week expected."); + return((TIME)0); } - wday = atoi (val); + token = next_token(&val, NULL, cfile); /* consume day of week */ + wday = atoi(val); /* Year... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn (cfile, "numeric year expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric year expected."); + return((TIME)0); } + token = next_token(&val, NULL, cfile); /* consume year */ /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until somebody invents a time machine, I think we can safely disregard it. This actually works around a stupid Y2K bug that was present in a very early beta release of dhcpd. */ - year = atoi (val); + year = atoi(val); if (year > 1900) year -= 1900; /* Slash separating year from month... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != SLASH) { - parse_warn (cfile, - "expected slash separating year from month."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, + "expected slash separating year from month."); + return((TIME)0); } + token = next_token(&val, NULL, cfile); /* consume SLASH */ /* Month... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn (cfile, "numeric month expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric month expected."); + return((TIME)0); } - mon = atoi (val) - 1; + token = next_token(&val, NULL, cfile); /* consume month */ + mon = atoi(val) - 1; /* Slash separating month from day... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != SLASH) { - parse_warn (cfile, - "expected slash separating month from day."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, + "expected slash separating month from day."); + return((TIME)0); } + token = next_token(&val, NULL, cfile); /* consume SLASH */ /* Day of month... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn (cfile, "numeric day of month expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric day of month expected."); + return((TIME)0); } - mday = atoi (val); + token = next_token(&val, NULL, cfile); /* consume day of month */ + mday = atoi(val); /* Hour... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn (cfile, "numeric hour expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric hour expected."); + return((TIME)0); } - hour = atoi (val); + token = next_token(&val, NULL, cfile); /* consume hour */ + hour = atoi(val); /* Colon separating hour from minute... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != COLON) { - parse_warn (cfile, - "expected colon separating hour from minute."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, + "expected colon separating hour from minute."); + return((TIME)0); } + token = next_token(&val, NULL, cfile); /* consume colon */ /* Minute... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn (cfile, "numeric minute expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric minute expected."); + return((TIME)0); } - min = atoi (val); + token = next_token(&val, NULL, cfile); /* consume minute */ + min = atoi(val); /* Colon separating minute from second... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != COLON) { - parse_warn (cfile, - "expected colon separating minute from second."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, + "expected colon separating minute from second."); + return((TIME)0); } + token = next_token(&val, NULL, cfile); /* consume colon */ /* Second... */ - token = next_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token != NUMBER) { - parse_warn (cfile, "numeric second expected."); if (token != SEMI) - skip_to_semi (cfile); - return (TIME)0; + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "numeric second expected."); + return((TIME)0); } - sec = atoi (val); + token = next_token(&val, NULL, cfile); /* consume second */ + sec = atoi(val); - token = peek_token (&val, (unsigned *)0, cfile); + tzoff = 0; + token = peek_token(&val, NULL, cfile); if (token == NUMBER) { - token = next_token (&val, (unsigned *)0, cfile); - tzoff = atoi (val); - } else - tzoff = 0; + token = next_token(&val, NULL, cfile); /* consume tzoff */ + tzoff = atoi(val); + } else if (token != SEMI) { + token = next_token(&val, NULL, cfile); + parse_warn(cfile, + "Time zone offset or semicolon expected."); + return((TIME)0); + } /* Guess the time value... */ guess = ((((((365 * (year - 70) + /* Days in years since '70 */ @@ -1041,21 +1059,25 @@ parse_date_core(cfile) is reread), the error could accumulate into something significant. */ - return guess; + return((TIME)guess); } -/* Wrapper to consume the semicolon after the date */ +/* + * Wrapper to consume the semicolon after the date + * :== date semi + */ + TIME parse_date(cfile) struct parse *cfile; { - int guess; + TIME guess; guess = parse_date_core(cfile); /* Make sure the date ends in a semicolon... */ if (!parse_semi(cfile)) - return 0; - return guess; + return((TIME)0); + return(guess); } |