mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-22 18:07:25 +00:00
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]
This commit is contained in:
parent
8bd445a1c1
commit
83d409ae59
4
RELNOTES
4
RELNOTES
@ -103,6 +103,10 @@ work on other platforms. Please report any problems and suggested fixes to
|
|||||||
- Two identical log messages for commit_leases() have been disambiguated.
|
- Two identical log messages for commit_leases() have been disambiguated.
|
||||||
[ISC-Bugs #18915]
|
[ISC-Bugs #18915]
|
||||||
|
|
||||||
|
- 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.2.0b2
|
Changes since 4.2.0b2
|
||||||
|
|
||||||
- Add declaration for variable in debug code in alloc.c. [ISC-Bugs #21472]
|
- Add declaration for variable in debug code in alloc.c. [ISC-Bugs #21472]
|
||||||
|
186
common/parse.c
186
common/parse.c
@ -889,9 +889,10 @@ void convert_num (cfile, buf, str, base, size)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
|
* 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 NUMBER SLASH NUMBER SLASH NUMBER
|
||||||
* NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI |
|
* NUMBER COLON NUMBER COLON NUMBER NUMBER |
|
||||||
|
* EPOCH NUMBER |
|
||||||
* NEVER
|
* NEVER
|
||||||
*
|
*
|
||||||
* Dates are stored in UTC or with a timezone offset; first number is day
|
* Dates are stored in UTC or with a timezone offset; first number is day
|
||||||
@ -900,7 +901,10 @@ void convert_num (cfile, buf, str, base, size)
|
|||||||
* optional.
|
* optional.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* just parse the date */
|
/*
|
||||||
|
* just parse the date
|
||||||
|
* any trailing semi must be consumed by the caller of this routine
|
||||||
|
*/
|
||||||
TIME
|
TIME
|
||||||
parse_date_core(cfile)
|
parse_date_core(cfile)
|
||||||
struct parse *cfile;
|
struct parse *cfile;
|
||||||
@ -909,157 +913,171 @@ parse_date_core(cfile)
|
|||||||
int tzoff, wday, year, mon, mday, hour, min, sec;
|
int tzoff, wday, year, mon, mday, hour, min, sec;
|
||||||
const char *val;
|
const char *val;
|
||||||
enum dhcp_token token;
|
enum dhcp_token token;
|
||||||
static int months [11] = { 31, 59, 90, 120, 151, 181,
|
static int months[11] = { 31, 59, 90, 120, 151, 181,
|
||||||
212, 243, 273, 304, 334 };
|
212, 243, 273, 304, 334 };
|
||||||
|
|
||||||
/* Day of week, or "never"... */
|
/* "never", "epoch" or day of week */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token == NEVER) {
|
if (token == NEVER) {
|
||||||
if (!parse_semi (cfile))
|
token = next_token(&val, NULL, cfile); /* consume NEVER */
|
||||||
return 0;
|
return(MAX_TIME);
|
||||||
return MAX_TIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This indicates 'local' time format. */
|
/* This indicates 'local' time format. */
|
||||||
if (token == EPOCH) {
|
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) {
|
if (token != NUMBER) {
|
||||||
parse_warn(cfile, "Seconds since epoch expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi(cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
parse_warn(cfile, "Seconds since epoch expected.");
|
||||||
|
return((TIME)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token = next_token(&val, NULL, cfile); /* consume number */
|
||||||
guess = atoi(val);
|
guess = atoi(val);
|
||||||
|
|
||||||
if (!parse_semi(cfile))
|
return((TIME)guess);
|
||||||
return (TIME)0;
|
|
||||||
|
|
||||||
return guess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric day of week expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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... */
|
/* Year... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric year expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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
|
/* 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
|
somebody invents a time machine, I think we can safely disregard
|
||||||
it. This actually works around a stupid Y2K bug that was present
|
it. This actually works around a stupid Y2K bug that was present
|
||||||
in a very early beta release of dhcpd. */
|
in a very early beta release of dhcpd. */
|
||||||
year = atoi (val);
|
year = atoi(val);
|
||||||
if (year > 1900)
|
if (year > 1900)
|
||||||
year -= 1900;
|
year -= 1900;
|
||||||
|
|
||||||
/* Slash separating year from month... */
|
/* Slash separating year from month... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != SLASH) {
|
if (token != SLASH) {
|
||||||
parse_warn (cfile,
|
|
||||||
"expected slash separating year from month.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
parse_warn(cfile,
|
||||||
|
"expected slash separating year from month.");
|
||||||
|
return((TIME)0);
|
||||||
}
|
}
|
||||||
|
token = next_token(&val, NULL, cfile); /* consume SLASH */
|
||||||
|
|
||||||
/* Month... */
|
/* Month... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric month expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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... */
|
/* Slash separating month from day... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != SLASH) {
|
if (token != SLASH) {
|
||||||
parse_warn (cfile,
|
|
||||||
"expected slash separating month from day.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
parse_warn(cfile,
|
||||||
|
"expected slash separating month from day.");
|
||||||
|
return((TIME)0);
|
||||||
}
|
}
|
||||||
|
token = next_token(&val, NULL, cfile); /* consume SLASH */
|
||||||
|
|
||||||
/* Day of month... */
|
/* Day of month... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric day of month expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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... */
|
/* Hour... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric hour expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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... */
|
/* Colon separating hour from minute... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != COLON) {
|
if (token != COLON) {
|
||||||
parse_warn (cfile,
|
|
||||||
"expected colon separating hour from minute.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
parse_warn(cfile,
|
||||||
|
"expected colon separating hour from minute.");
|
||||||
|
return((TIME)0);
|
||||||
}
|
}
|
||||||
|
token = next_token(&val, NULL, cfile); /* consume colon */
|
||||||
|
|
||||||
/* Minute... */
|
/* Minute... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric minute expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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... */
|
/* Colon separating minute from second... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != COLON) {
|
if (token != COLON) {
|
||||||
parse_warn (cfile,
|
|
||||||
"expected colon separating minute from second.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
parse_warn(cfile,
|
||||||
|
"expected colon separating minute from second.");
|
||||||
|
return((TIME)0);
|
||||||
}
|
}
|
||||||
|
token = next_token(&val, NULL, cfile); /* consume colon */
|
||||||
|
|
||||||
/* Second... */
|
/* Second... */
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token != NUMBER) {
|
if (token != NUMBER) {
|
||||||
parse_warn (cfile, "numeric second expected.");
|
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
token = next_token(&val, NULL, cfile);
|
||||||
return (TIME)0;
|
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) {
|
if (token == NUMBER) {
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = next_token(&val, NULL, cfile); /* consume tzoff */
|
||||||
tzoff = atoi (val);
|
tzoff = atoi(val);
|
||||||
} else
|
} else if (token != SEMI) {
|
||||||
tzoff = 0;
|
token = next_token(&val, NULL, cfile);
|
||||||
|
parse_warn(cfile,
|
||||||
|
"Time zone offset or semicolon expected.");
|
||||||
|
return((TIME)0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Guess the time value... */
|
/* Guess the time value... */
|
||||||
guess = ((((((365 * (year - 70) + /* Days in years since '70 */
|
guess = ((((((365 * (year - 70) + /* Days in years since '70 */
|
||||||
@ -1082,21 +1100,25 @@ parse_date_core(cfile)
|
|||||||
is reread), the error could accumulate into something
|
is reread), the error could accumulate into something
|
||||||
significant. */
|
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
|
TIME
|
||||||
parse_date(cfile)
|
parse_date(cfile)
|
||||||
struct parse *cfile;
|
struct parse *cfile;
|
||||||
{
|
{
|
||||||
int guess;
|
TIME guess;
|
||||||
guess = parse_date_core(cfile);
|
guess = parse_date_core(cfile);
|
||||||
|
|
||||||
/* Make sure the date ends in a semicolon... */
|
/* Make sure the date ends in a semicolon... */
|
||||||
if (!parse_semi(cfile))
|
if (!parse_semi(cfile))
|
||||||
return 0;
|
return((TIME)0);
|
||||||
return guess;
|
return(guess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user