[1/3] winhttp: Parse cookie attributes.

Hans Leidekker hans at codeweavers.com
Tue Feb 21 02:24:36 CST 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/winhttp/cookie.c | 118 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 88 insertions(+), 30 deletions(-)

diff --git a/dlls/winhttp/cookie.c b/dlls/winhttp/cookie.c
index 769055be21..ec5dbc4979 100644
--- a/dlls/winhttp/cookie.c
+++ b/dlls/winhttp/cookie.c
@@ -167,17 +167,79 @@ static cookie_t *parse_cookie( const WCHAR *string )
     return cookie;
 }
 
+struct attr
+{
+    WCHAR *name;
+    WCHAR *value;
+};
+
+static void free_attr( struct attr *attr )
+{
+    if (!attr) return;
+    heap_free( attr->name );
+    heap_free( attr->value );
+    heap_free( attr );
+}
+
+static struct attr *parse_attr( const WCHAR *str, int *used )
+{
+    const WCHAR *p = str, *q;
+    struct attr *attr;
+    int len;
+
+    while (*p == ' ') p++;
+    q = p;
+    while (*q && *q != ' ' && *q != '=' && *q != ';') q++;
+    len = q - p;
+    if (!len) return NULL;
+
+    if (!(attr = heap_alloc( sizeof(struct attr) ))) return NULL;
+    if (!(attr->name = heap_alloc( (len + 1) * sizeof(WCHAR) )))
+    {
+        heap_free( attr );
+        return NULL;
+    }
+    memcpy( attr->name, p, len * sizeof(WCHAR) );
+    attr->name[len] = 0;
+    attr->value = NULL;
+
+    p = q;
+    while (*p == ' ') p++;
+    if (*p++ == '=')
+    {
+        while (*p == ' ') p++;
+        q = p;
+        while (*q && *q != ';') q++;
+        len = q - p;
+        while (len && p[len - 1] == ' ') len--;
+
+        if (!(attr->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
+        {
+            free_attr( attr );
+            return NULL;
+        }
+        memcpy( attr->value, p, len * sizeof(WCHAR) );
+        attr->value[len] = 0;
+    }
+
+    while (*q == ' ') q++;
+    if (*q == ';') q++;
+    *used = q - str;
+
+    return attr;
+}
+
 BOOL set_cookies( request_t *request, const WCHAR *cookies )
 {
     static const WCHAR pathW[] = {'p','a','t','h',0};
     static const WCHAR domainW[] = {'d','o','m','a','i','n',0};
-
     BOOL ret = FALSE;
-    WCHAR *buffer, *p, *q, *r;
+    WCHAR *buffer, *p;
     WCHAR *cookie_domain = NULL, *cookie_path = NULL;
+    struct attr *attr, *domain = NULL, *path = NULL;
     session_t *session = request->connect->session;
     cookie_t *cookie;
-    int len;
+    int len, used;
 
     len = strlenW( cookies );
     if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
@@ -191,32 +253,26 @@ BOOL set_cookies( request_t *request, const WCHAR *cookies )
         heap_free( buffer );
         return FALSE;
     }
-    if ((q = strstrW( p, domainW ))) /* FIXME: do real attribute parsing */
-    {
-        while (*q && *q != '=') q++;
-        if (!*q) goto end;
-
-        r = ++q;
-        while (*r && *r != ';') r++;
-        len = r - q;
-
-        if (!(cookie_domain = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
-        memcpy( cookie_domain, q, len * sizeof(WCHAR) );
-        cookie_domain[len] = 0;
-
-    }
-    if ((q = strstrW( p, pathW )))
+    len = strlenW( p );
+    while (len && (attr = parse_attr( p, &used )))
     {
-        while (*q && *q != '=') q++;
-        if (!*q) goto end;
-
-        r = ++q;
-        while (*r && *r != ';') r++;
-        len = r - q;
-
-        if (!(cookie_path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
-        memcpy( cookie_path, q, len * sizeof(WCHAR) );
-        cookie_path[len] = 0;
+        if (!strcmpW( attr->name, domainW ))
+        {
+            domain = attr;
+            cookie_domain = attr->value;
+        }
+        else if (!strcmpW( attr->name, pathW ))
+        {
+            path = attr;
+            cookie_path = attr->value;
+        }
+        else
+        {
+            FIXME( "unhandled attribute %s\n", debugstr_w(attr->name) );
+            free_attr( attr );
+        }
+        len -= used;
+        p += used;
     }
     if (!cookie_domain && !(cookie_domain = strdupW( request->connect->servername ))) goto end;
     if (!cookie_path && !(cookie_path = strdupW( request->path ))) goto end;
@@ -226,8 +282,10 @@ BOOL set_cookies( request_t *request, const WCHAR *cookies )
 
 end:
     if (!ret) free_cookie( cookie );
-    heap_free( cookie_domain );
-    heap_free( cookie_path );
+    if (domain) free_attr( domain );
+    else heap_free( cookie_domain );
+    if (path) free_attr( path );
+    else heap_free( cookie_path );
     heap_free( buffer );
     return ret;
 }
-- 
2.11.0




More information about the wine-patches mailing list