Juan Lang : wininet: Accept RFC 850 dates in HTTP headers.
Alexandre Julliard
julliard at winehq.org
Mon Oct 24 13:43:53 CDT 2011
Module: wine
Branch: master
Commit: aeca2f98fa6086b0a83d9acece336e91a6a6df6f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=aeca2f98fa6086b0a83d9acece336e91a6a6df6f
Author: Juan Lang <juan.lang at gmail.com>
Date: Fri Oct 21 22:55:14 2011 -0700
wininet: Accept RFC 850 dates in HTTP headers.
---
dlls/wininet/http.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 134 insertions(+), 12 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 50630ba..d1a870b 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -3989,7 +3989,7 @@ static void HTTP_InsertCookies(http_request_t *request)
heap_free(cookies);
}
-static WORD HTTP_ParseDay(LPCWSTR day)
+static WORD HTTP_ParseWkday(LPCWSTR day)
{
static const WCHAR days[7][4] = {{ 's','u','n',0 },
{ 'm','o','n',0 },
@@ -4107,7 +4107,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft)
dayPtr - day < sizeof(day) / sizeof(day[0]) - 1; ptr++, dayPtr++)
*dayPtr = *ptr;
*dayPtr = 0;
- st.wDayOfWeek = HTTP_ParseDay(day);
+ st.wDayOfWeek = HTTP_ParseWkday(day);
if (st.wDayOfWeek >= 7)
{
ERR("unexpected weekday %s\n", debugstr_w(day));
@@ -4186,15 +4186,15 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
return FALSE;
if (ptr - value != 3)
{
- ERR("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
+ WARN("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
return FALSE;
}
memcpy(day, value, (ptr - value) * sizeof(WCHAR));
day[3] = 0;
- st.wDayOfWeek = HTTP_ParseDay(day);
+ st.wDayOfWeek = HTTP_ParseWkday(day);
if (st.wDayOfWeek > 6)
{
- ERR("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
+ WARN("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
return FALSE;
}
ptr++;
@@ -4205,7 +4205,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
num = strtoulW(ptr, &nextPtr, 10);
if (!nextPtr || nextPtr <= ptr || !num || num > 31)
{
- ERR("unexpected day %s\n", debugstr_w(value));
+ WARN("unexpected day %s\n", debugstr_w(value));
return FALSE;
}
ptr = nextPtr;
@@ -4222,7 +4222,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
st.wMonth = HTTP_ParseMonth(month);
if (!st.wMonth || st.wMonth > 12)
{
- ERR("unexpected month %s\n", debugstr_w(month));
+ WARN("unexpected month %s\n", debugstr_w(month));
return FALSE;
}
@@ -4252,11 +4252,125 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
return SystemTimeToFileTime(&st, ft);
}
-/* FIXME: only accepts dates in RFC 1123 format and asctime() format,
- * which may not be the only formats actually seen in the wild.
- * http://www.hackcraft.net/web/datetime/ suggests at least RFC 850 dates
- * should be accepted as well.
- */
+static WORD HTTP_ParseWeekday(LPCWSTR day)
+{
+ static const WCHAR days[7][10] = {{ 's','u','n','d','a','y',0 },
+ { 'm','o','n','d','a','y',0 },
+ { 't','u','e','s','d','a','y',0 },
+ { 'w','e','d','n','e','s','d','a','y',0 },
+ { 't','h','u','r','s','d','a','y',0 },
+ { 'f','r','i','d','a','y',0 },
+ { 's','a','t','u','r','d','a','y',0 }};
+ int i;
+ for (i = 0; i < sizeof(days)/sizeof(*days); i++)
+ if (!strcmpiW(day, days[i]))
+ return i;
+
+ /* Invalid */
+ return 7;
+}
+
+static BOOL HTTP_ParseRfc850Date(LPCWSTR value, FILETIME *ft)
+{
+ static const WCHAR gmt[]= { 'G','M','T',0 };
+ WCHAR *nextPtr, day[10], month[4], *monthPtr;
+ LPCWSTR ptr;
+ unsigned long num;
+ SYSTEMTIME st = { 0 };
+
+ ptr = strchrW(value, ',');
+ if (!ptr)
+ return FALSE;
+ if (ptr - value == 3)
+ {
+ memcpy(day, value, (ptr - value) * sizeof(WCHAR));
+ day[3] = 0;
+ st.wDayOfWeek = HTTP_ParseWkday(day);
+ if (st.wDayOfWeek > 6)
+ {
+ ERR("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
+ return FALSE;
+ }
+ }
+ else if (ptr - value <= sizeof(day) / sizeof(day[0]))
+ {
+ memcpy(day, value, (ptr - value) * sizeof(WCHAR));
+ day[ptr - value + 1] = 0;
+ st.wDayOfWeek = HTTP_ParseWeekday(day);
+ if (st.wDayOfWeek > 6)
+ {
+ ERR("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
+ return FALSE;
+ }
+ }
+ else
+ {
+ ERR("unexpected weekday %s\n", debugstr_wn(value, ptr - value));
+ return FALSE;
+ }
+ ptr++;
+
+ while (isspaceW(*ptr))
+ ptr++;
+
+ num = strtoulW(ptr, &nextPtr, 10);
+ if (!nextPtr || nextPtr <= ptr || !num || num > 31)
+ {
+ ERR("unexpected day %s\n", debugstr_w(value));
+ return FALSE;
+ }
+ ptr = nextPtr;
+ st.wDay = (WORD)num;
+
+ if (*ptr != '-')
+ {
+ ERR("unexpected month format %s\n", debugstr_w(ptr));
+ return FALSE;
+ }
+ ptr++;
+
+ for (monthPtr = month; *ptr != '-' &&
+ monthPtr - month < sizeof(month) / sizeof(month[0]) - 1;
+ monthPtr++, ptr++)
+ *monthPtr = *ptr;
+ *monthPtr = 0;
+ st.wMonth = HTTP_ParseMonth(month);
+ if (!st.wMonth || st.wMonth > 12)
+ {
+ ERR("unexpected month %s\n", debugstr_w(month));
+ return FALSE;
+ }
+
+ if (*ptr != '-')
+ {
+ ERR("unexpected year format %s\n", debugstr_w(ptr));
+ return FALSE;
+ }
+ ptr++;
+
+ num = strtoulW(ptr, &nextPtr, 10);
+ if (!nextPtr || nextPtr <= ptr || num < 1601 || num > 30827)
+ {
+ ERR("unexpected year %s\n", debugstr_w(value));
+ return FALSE;
+ }
+ ptr = nextPtr;
+ st.wYear = (WORD)num;
+
+ if (!HTTP_ParseTime(&st, &ptr))
+ return FALSE;
+
+ while (isspaceW(*ptr))
+ ptr++;
+
+ if (strcmpW(ptr, gmt))
+ {
+ ERR("unexpected time zone %s\n", debugstr_w(ptr));
+ return FALSE;
+ }
+ return SystemTimeToFileTime(&st, ft);
+}
+
static BOOL HTTP_ParseDate(LPCWSTR value, FILETIME *ft)
{
static const WCHAR zero[] = { '0',0 };
@@ -4268,7 +4382,15 @@ static BOOL HTTP_ParseDate(LPCWSTR value, FILETIME *ft)
ret = TRUE;
}
else if (strchrW(value, ','))
+ {
ret = HTTP_ParseRfc1123Date(value, ft);
+ if (!ret)
+ {
+ ret = HTTP_ParseRfc850Date(value, ft);
+ if (!ret)
+ ERR("unexpected date format %s\n", debugstr_w(value));
+ }
+ }
else
{
ret = HTTP_ParseDateAsAsctime(value, ft);
More information about the wine-cvs
mailing list