HTTP Compliance: Make date parser more strict to better handle extended
Expires
Check that there is no zone or zone is "GMT" in parse_date_elements().
Make sure there is no junk at the end of date in parse_date().
Co-Advisor test case:
test_case/rfc2616/invalidExpiresMakesStale-rfc1123x
HTTP Compliance: Make date parser more strict to better handle extended Expires
Check that there is no zone or zone is "GMT" in parse_date_elements().
Make sure there is no junk at the end of date in parse_date().
Co-Advisor test case:
test_case/rfc2616/invalidExpiresMakesStale-rfc1123x
=== modified file 'lib/rfc1123.c'
--- lib/rfc1123.c 2010-03-31 15:59:21 +0000
+++ lib/rfc1123.c 2010-09-19 07:26:04 +0000
@@ -96,41 +96,41 @@ tmSaneValues(struct tm *tm)
if (tm->tm_sec < 0 || tm->tm_sec > 59)
return 0;
if (tm->tm_min < 0 || tm->tm_min > 59)
return 0;
if (tm->tm_hour < 0 || tm->tm_hour > 23)
return 0;
if (tm->tm_mday < 1 || tm->tm_mday > 31)
return 0;
if (tm->tm_mon < 0 || tm->tm_mon > 11)
return 0;
return 1;
}
static struct tm *
parse_date_elements(const char *day, const char *month, const char *year,
const char *aTime, const char *zone) {
static struct tm tm;
char *t;
memset(&tm, 0, sizeof(tm));
- if (!day || !month || !year || !aTime)
+ if (!day || !month || !year || !aTime || (zone && strcmp(zone, "GMT")))
return NULL;
tm.tm_mday = atoi(day);
tm.tm_mon = make_month(month);
if (tm.tm_mon < 0)
return NULL;
tm.tm_year = atoi(year);
if (strlen(year) == 4)
tm.tm_year -= 1900;
else if (tm.tm_year < 70)
tm.tm_year += 100;
else if (tm.tm_year > 19000)
tm.tm_year -= 19000;
tm.tm_hour = make_num(aTime);
t = strchr(aTime, ':');
if (!t)
return NULL;
t++;
tm.tm_min = atoi(t);
t = strchr(t, ':');
if (t)
@@ -153,46 +153,50 @@ parse_date(const char *str) {
xstrncpy(tmp, str, 64);
for (t = strtok(tmp, ", "); t; t = strtok(NULL, ", ")) {
if (xisdigit(*t)) {
if (!day) {
day = t;
t = strchr(t, '-');
if (t) {
*t++ = '\0';
month = t;
t = strchr(t, '-');
if (!t)
return NULL;
*t++ = '\0';
year = t;
}
} else if (strchr(t, ':'))
timestr = t;
else if (!year)
year = t;
+ else
+ return NULL;
} else if (!wday)
wday = t;
else if (!month)
month = t;
else if (!zone)
zone = t;
+ else
+ return NULL;
}
tm = parse_date_elements(day, month, year, timestr, zone);
return tm;
}
time_t
parse_rfc1123(const char *str)
{
struct tm *tm;
time_t t;
if (NULL == str)
return -1;
tm = parse_date(str);
if (!tm)
return -1;
tm->tm_isdst = -1;
#if HAVE_TIMEGM
t = timegm(tm);
#elif HAVE_TM_TM_GMTOFF