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