Commit 4707b448 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

wininet: Rewrite structs storing cookies to represent domains as a tree.

parent ffec675b
......@@ -53,30 +53,42 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
* Cookies could use A LOT OF MEMORY. We need some kind of memory management here!
*/
typedef struct _cookie_domain cookie_domain;
typedef struct _cookie cookie;
struct _cookie_domain_t;
struct _cookie_container_t;
struct _cookie
{
typedef struct _cookie_t {
struct list entry;
struct _cookie_domain *parent;
struct _cookie_container_t *container;
LPWSTR lpCookieName;
LPWSTR lpCookieData;
WCHAR *name;
WCHAR *data;
DWORD flags;
FILETIME expiry;
FILETIME create;
};
} cookie_t;
struct _cookie_domain
{
typedef struct _cookie_container_t {
struct list entry;
LPWSTR lpCookieDomain;
LPWSTR lpCookiePath;
WCHAR *path;
struct _cookie_domain_t *domain;
struct list cookie_list;
};
} cookie_container_t;
typedef struct _cookie_domain_t {
struct list entry;
WCHAR *domain;
unsigned subdomain_len;
struct _cookie_domain_t *parent;
struct list subdomain_list;
/* List of stored paths sorted by length of the path. */
struct list path_list;
} cookie_domain_t;
static CRITICAL_SECTION cookie_cs;
static CRITICAL_SECTION_DEBUG cookie_cs_debug =
......@@ -88,14 +100,172 @@ static CRITICAL_SECTION_DEBUG cookie_cs_debug =
static CRITICAL_SECTION cookie_cs = { &cookie_cs_debug, -1, 0, 0, 0, 0 };
static struct list domain_list = LIST_INIT(domain_list);
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data,
FILETIME expiry, FILETIME create, DWORD flags);
static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName);
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain);
static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path);
static void COOKIE_deleteDomain(cookie_domain *deadDomain);
static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
cookie_domain *searchDomain, BOOL allow_partial);
static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
{
const WCHAR *ptr = domain + strlenW(domain), *ptr_end, *subdomain_ptr;
cookie_domain_t *iter, *current_domain, *prev_domain = NULL;
struct list *current_list = &domain_list;
while(1) {
for(ptr_end = ptr--; ptr > domain && *ptr != '.'; ptr--);
subdomain_ptr = *ptr == '.' ? ptr+1 : ptr;
current_domain = NULL;
LIST_FOR_EACH_ENTRY(iter, current_list, cookie_domain_t, entry) {
if(ptr_end-subdomain_ptr == iter->subdomain_len && !memcmp(subdomain_ptr, iter->domain, iter->subdomain_len)) {
current_domain = iter;
break;
}
}
if(!current_domain) {
if(!create)
return prev_domain;
current_domain = heap_alloc(sizeof(*current_domain));
if(!current_domain)
return NULL;
current_domain->domain = heap_strdupW(subdomain_ptr);
if(!current_domain->domain) {
heap_free(current_domain);
return NULL;
}
current_domain->subdomain_len = ptr_end-subdomain_ptr;
current_domain->parent = prev_domain;
list_init(&current_domain->path_list);
list_init(&current_domain->subdomain_list);
list_add_tail(current_list, &current_domain->entry);
}
if(ptr == domain)
return current_domain;
prev_domain = current_domain;
current_list = &current_domain->subdomain_list;
}
}
static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR *path, BOOL create)
{
cookie_domain_t *cookie_domain;
cookie_container_t *cookie_container, *iter;
size_t path_len, len;
cookie_domain = get_cookie_domain(domain, create);
if(!cookie_domain)
return NULL;
path_len = strlenW(path);
LIST_FOR_EACH_ENTRY(cookie_container, &cookie_domain->path_list, cookie_container_t, entry) {
len = strlenW(cookie_container->path);
if(len < path_len)
break;
if(!strcmpiW(cookie_container->path, path))
return cookie_container;
}
if(!create)
return NULL;
cookie_container = heap_alloc(sizeof(*cookie_container));
if(!cookie_container)
return NULL;
cookie_container->path = heap_strdupW(path);
if(!cookie_container->path) {
heap_free(cookie_container);
return NULL;
}
cookie_container->domain = cookie_domain;
list_init(&cookie_container->cookie_list);
LIST_FOR_EACH_ENTRY(iter, &cookie_domain->path_list, cookie_container_t, entry) {
if(strlenW(iter->path) <= path_len) {
list_add_before(&iter->entry, &cookie_container->entry);
return cookie_container;
}
}
list_add_tail(&cookie_domain->path_list, &cookie_container->entry);
return cookie_container;
}
static void delete_cookie(cookie_t *cookie)
{
list_remove(&cookie->entry);
heap_free(cookie->name);
heap_free(cookie->data);
heap_free(cookie);
}
static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME expiry, FILETIME create_time, DWORD flags)
{
cookie_t *new_cookie;
new_cookie = heap_alloc(sizeof(*new_cookie));
if(!new_cookie)
return NULL;
new_cookie->expiry = expiry;
new_cookie->create = create_time;
new_cookie->flags = flags;
list_init(&new_cookie->entry);
new_cookie->name = heap_strdupW(name);
new_cookie->data = heap_strdupW(data);
if((name && !new_cookie->name) || (data && !new_cookie->data)) {
delete_cookie(new_cookie);
return NULL;
}
return new_cookie;
}
static cookie_t *find_cookie(cookie_container_t *container, const WCHAR *name)
{
cookie_t *iter;
LIST_FOR_EACH_ENTRY(iter, &container->cookie_list, cookie_t, entry) {
if(!strcmpiW(iter->name, name))
return iter;
}
return NULL;
}
static void add_cookie(cookie_container_t *container, cookie_t *new_cookie)
{
TRACE("Adding %s=%s to %s %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
debugstr_w(container->domain->domain), debugstr_w(container->path));
list_add_tail(&container->cookie_list, &new_cookie->entry);
new_cookie->container = container;
}
static void replace_cookie(cookie_container_t *container, cookie_t *new_cookie)
{
cookie_t *old_cookie;
old_cookie = find_cookie(container, new_cookie->name);
if(old_cookie)
delete_cookie(old_cookie);
add_cookie(container, new_cookie);
}
static BOOL cookie_match_path(cookie_container_t *container, const WCHAR *path)
{
return !strncmpiW(container->path, path, strlenW(container->path));
}
static BOOL create_cookie_url(LPCWSTR domain, LPCWSTR path, WCHAR *buf, DWORD buf_len)
{
......@@ -145,9 +315,8 @@ static BOOL create_cookie_url(LPCWSTR domain, LPCWSTR path, WCHAR *buf, DWORD bu
static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
{
INTERNET_CACHE_ENTRY_INFOW *info;
cookie_domain *domain_container = NULL;
cookie *old_cookie;
struct list *iter;
cookie_container_t *cookie_container;
cookie_t *new_cookie;
WCHAR cookie_url[MAX_PATH];
HANDLE cookie;
char *str = NULL, *pbeg, *pend;
......@@ -179,19 +348,9 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
str[size] = 0;
UnlockUrlCacheEntryStream(cookie, 0);
LIST_FOR_EACH(iter, &domain_list)
{
domain_container = LIST_ENTRY(iter, cookie_domain, entry);
if(COOKIE_matchDomain(domain, path, domain_container, FALSE))
break;
domain_container = NULL;
}
if(!domain_container)
domain_container = COOKIE_addDomain(domain, path);
if(!domain_container) {
heap_free(str);
cookie_container = get_cookie_container(domain, path, TRUE);
if(!cookie_container)
return FALSE;
}
GetSystemTimeAsFileTime(&time);
for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
......@@ -227,12 +386,18 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
break;
if(CompareFileTime(&time, &expiry) <= 0) {
if((old_cookie = COOKIE_findCookie(domain_container, name)))
COOKIE_deleteCookie(old_cookie, FALSE);
COOKIE_addCookie(domain_container, name, data, expiry, create, flags);
new_cookie = alloc_cookie(NULL, NULL, expiry, create, flags);
if(!new_cookie)
break;
new_cookie->name = name;
new_cookie->data = data;
replace_cookie(cookie_container, new_cookie);
}else {
heap_free(name);
heap_free(data);
}
heap_free(name);
heap_free(data);
}
heap_free(str);
heap_free(name);
......@@ -241,27 +406,27 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
return TRUE;
}
static BOOL save_persistent_cookie(cookie_domain *domain)
static BOOL save_persistent_cookie(cookie_container_t *container)
{
static const WCHAR txtW[] = {'t','x','t',0};
WCHAR cookie_url[MAX_PATH], cookie_file[MAX_PATH];
HANDLE cookie_handle;
cookie *cookie_container = NULL, *cookie_iter;
cookie_t *cookie_container = NULL, *cookie_iter;
BOOL do_save = FALSE;
char buf[64], *dyn_buf;
FILETIME time;
if (!create_cookie_url(domain->lpCookieDomain, domain->lpCookiePath, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
if (!create_cookie_url(container->domain->domain, container->path, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
return FALSE;
/* check if there's anything to save */
GetSystemTimeAsFileTime(&time);
LIST_FOR_EACH_ENTRY_SAFE(cookie_container, cookie_iter, &domain->cookie_list, cookie, entry)
LIST_FOR_EACH_ENTRY_SAFE(cookie_container, cookie_iter, &container->cookie_list, cookie_t, entry)
{
if((cookie_container->expiry.dwLowDateTime || cookie_container->expiry.dwHighDateTime)
&& CompareFileTime(&time, &cookie_container->expiry) > 0) {
COOKIE_deleteCookie(cookie_container, FALSE);
delete_cookie(cookie_container);
continue;
}
......@@ -283,12 +448,12 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
return FALSE;
}
LIST_FOR_EACH_ENTRY(cookie_container, &domain->cookie_list, cookie, entry)
LIST_FOR_EACH_ENTRY(cookie_container, &container->cookie_list, cookie_t, entry)
{
if(cookie_container->flags & INTERNET_COOKIE_IS_SESSION)
continue;
dyn_buf = heap_strdupWtoA(cookie_container->lpCookieName);
dyn_buf = heap_strdupWtoA(cookie_container->name);
if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
......@@ -300,7 +465,7 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
break;
}
dyn_buf = heap_strdupWtoA(cookie_container->lpCookieData);
dyn_buf = heap_strdupWtoA(cookie_container->data);
if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
......@@ -312,7 +477,7 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
break;
}
dyn_buf = heap_strdupWtoA(domain->lpCookieDomain);
dyn_buf = heap_strdupWtoA(container->domain->domain);
if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
......@@ -320,7 +485,7 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
}
heap_free(dyn_buf);
dyn_buf = heap_strdupWtoA(domain->lpCookiePath);
dyn_buf = heap_strdupWtoA(container->path);
if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
......@@ -348,90 +513,6 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
return CommitUrlCacheEntryW(cookie_url, cookie_file, time, time, 0, NULL, 0, txtW, 0);
}
/* adds a cookie to the domain */
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data,
FILETIME expiry, FILETIME create, DWORD flags)
{
cookie *newCookie = heap_alloc(sizeof(cookie));
if (!newCookie)
return NULL;
newCookie->lpCookieName = heap_strdupW(name);
newCookie->lpCookieData = heap_strdupW(data);
if (!newCookie->lpCookieName || !newCookie->lpCookieData)
{
heap_free(newCookie->lpCookieName);
heap_free(newCookie->lpCookieData);
heap_free(newCookie);
return NULL;
}
newCookie->flags = flags;
newCookie->expiry = expiry;
newCookie->create = create;
TRACE("added cookie %p (data is %s)\n", newCookie, debugstr_w(data) );
list_add_tail(&domain->cookie_list, &newCookie->entry);
newCookie->parent = domain;
return newCookie;
}
/* finds a cookie in the domain matching the cookie name */
static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName)
{
struct list * cursor;
TRACE("(%p, %s)\n", domain, debugstr_w(lpszCookieName));
LIST_FOR_EACH(cursor, &domain->cookie_list)
{
cookie *searchCookie = LIST_ENTRY(cursor, cookie, entry);
BOOL candidate = TRUE;
if (candidate && lpszCookieName)
{
if (candidate && !searchCookie->lpCookieName)
candidate = FALSE;
if (candidate && strcmpW(lpszCookieName, searchCookie->lpCookieName) != 0)
candidate = FALSE;
}
if (candidate)
return searchCookie;
}
return NULL;
}
/* removes a cookie from the list, if its the last cookie we also remove the domain */
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain)
{
heap_free(deadCookie->lpCookieName);
heap_free(deadCookie->lpCookieData);
list_remove(&deadCookie->entry);
/* special case: last cookie, lets remove the domain to save memory */
if (list_empty(&deadCookie->parent->cookie_list) && deleteDomain)
COOKIE_deleteDomain(deadCookie->parent);
heap_free(deadCookie);
}
/* allocates a domain and adds it to the end */
static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path)
{
cookie_domain *newDomain = heap_alloc(sizeof(cookie_domain));
list_init(&newDomain->entry);
list_init(&newDomain->cookie_list);
newDomain->lpCookieDomain = heap_strdupW(domain);
newDomain->lpCookiePath = heap_strdupW(path);
list_add_tail(&domain_list, &newDomain->entry);
TRACE("Adding domain: %p\n", newDomain);
return newDomain;
}
static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostNameLen, LPWSTR path, int pathLen)
{
URL_COMPONENTSW UrlComponents;
......@@ -473,64 +554,6 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName
return TRUE;
}
/* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */
static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
cookie_domain *searchDomain, BOOL allow_partial)
{
TRACE("searching on domain %p\n", searchDomain);
if (lpszCookieDomain)
{
if (!searchDomain->lpCookieDomain)
return FALSE;
TRACE("comparing domain %s with %s\n",
debugstr_w(lpszCookieDomain),
debugstr_w(searchDomain->lpCookieDomain));
if (allow_partial && !strstrW(lpszCookieDomain, searchDomain->lpCookieDomain))
return FALSE;
else if (!allow_partial && lstrcmpW(lpszCookieDomain, searchDomain->lpCookieDomain) != 0)
return FALSE;
}
if (lpszCookiePath)
{
INT len;
TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath));
/* paths match at the beginning. so a path of /foo would match
* /foobar and /foo/bar
*/
if (!searchDomain->lpCookiePath)
return FALSE;
if (allow_partial)
{
len = lstrlenW(searchDomain->lpCookiePath);
if (strncmpiW(searchDomain->lpCookiePath, lpszCookiePath, len)!=0)
return FALSE;
}
else if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
return FALSE;
}
return TRUE;
}
/* remove a domain from the list and delete it */
static void COOKIE_deleteDomain(cookie_domain *deadDomain)
{
struct list * cursor;
while ((cursor = list_tail(&deadDomain->cookie_list)))
{
COOKIE_deleteCookie(LIST_ENTRY(cursor, cookie, entry), FALSE);
list_remove(cursor);
}
heap_free(deadDomain->lpCookieDomain);
heap_free(deadDomain->lpCookiePath);
list_remove(&deadDomain->entry);
heap_free(deadDomain);
}
DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD *size, DWORD flags)
{
static const WCHAR empty_path[] = { '/',0 };
......@@ -538,7 +561,8 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
unsigned cnt = 0, len, name_len, domain_count = 0, cookie_count = 0;
WCHAR *ptr, subpath[INTERNET_MAX_PATH_LENGTH];
const WCHAR *p;
cookie_domain *domain;
cookie_domain_t *domain;
cookie_container_t *container;
FILETIME tm;
GetSystemTimeAsFileTime(&tm);
......@@ -568,64 +592,77 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
while(ptr>subpath && ptr[-1]!='/') ptr--;
}while(ptr != subpath);
domain = get_cookie_domain(host, FALSE);
if(!domain) {
TRACE("Unknown host %s\n", debugstr_w(host));
LeaveCriticalSection(&cookie_cs);
return ERROR_NO_MORE_ITEMS;
}
ptr = cookie_data;
LIST_FOR_EACH_ENTRY(domain, &domain_list, cookie_domain, entry) {
struct list *cursor, *cursor2;
if(!COOKIE_matchDomain(host, path, domain, TRUE))
continue;
for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
TRACE("Trying %s domain...\n", debugstr_w(domain->domain));
domain_count++;
TRACE("found domain %p\n", domain);
LIST_FOR_EACH_ENTRY(container, &domain->path_list, cookie_container_t, entry) {
struct list *cursor, *cursor2;
LIST_FOR_EACH_SAFE(cursor, cursor2, &domain->cookie_list) {
cookie *cookie_iter = LIST_ENTRY(cursor, cookie, entry);
TRACE("path %s\n", debugstr_w(container->path));
/* check for expiry */
if((cookie_iter->expiry.dwLowDateTime != 0 || cookie_iter->expiry.dwHighDateTime != 0)
&& CompareFileTime(&tm, &cookie_iter->expiry) > 0)
{
TRACE("Found expired cookie. deleting\n");
COOKIE_deleteCookie(cookie_iter, FALSE);
if(!cookie_match_path(container, path))
continue;
}
if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
continue;
domain_count++;
TRACE("found domain %p\n", domain->domain);
if (cookie_count)
cnt += 2; /* '; ' */
cnt += name_len = strlenW(cookie_iter->lpCookieName);
if ((len = strlenW(cookie_iter->lpCookieData))) {
cnt += 1; /* = */
cnt += len;
}
LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
cookie_t *cookie_iter = LIST_ENTRY(cursor, cookie_t, entry);
if(ptr) {
if(*size > cnt) {
if(cookie_count) {
*ptr++ = ';';
*ptr++ = ' ';
}
/* check for expiry */
if((cookie_iter->expiry.dwLowDateTime != 0 || cookie_iter->expiry.dwHighDateTime != 0)
&& CompareFileTime(&tm, &cookie_iter->expiry) > 0) {
TRACE("Found expired cookie. deleting\n");
delete_cookie(cookie_iter);
continue;
}
memcpy(ptr, cookie_iter->lpCookieName, name_len*sizeof(WCHAR));
ptr += name_len;
if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
continue;
if(len) {
*ptr++ = '=';
memcpy(ptr, cookie_iter->lpCookieData, len*sizeof(WCHAR));
ptr += len;
}
if (cookie_count)
cnt += 2; /* '; ' */
cnt += name_len = strlenW(cookie_iter->name);
if ((len = strlenW(cookie_iter->data))) {
cnt += 1; /* = */
cnt += len;
}
if(ptr) {
if(*size > cnt) {
if(cookie_count) {
*ptr++ = ';';
*ptr++ = ' ';
}
memcpy(ptr, cookie_iter->name, name_len*sizeof(WCHAR));
ptr += name_len;
assert(cookie_data+cnt == ptr);
TRACE("Cookie: %s\n", debugstr_wn(cookie_data, cnt));
}else {
/* Stop writing data, just compute the size */
ptr = NULL;
if(len) {
*ptr++ = '=';
memcpy(ptr, cookie_iter->data, len*sizeof(WCHAR));
ptr += len;
}
assert(cookie_data+cnt == ptr);
TRACE("Cookie: %s\n", debugstr_wn(cookie_data, cnt));
}else {
/* Stop writing data, just compute the size */
ptr = NULL;
}
}
}
cookie_count++;
cookie_count++;
}
}
}
......@@ -815,15 +852,16 @@ BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_name, const WCHAR *cookie_data, DWORD flags)
{
cookie_domain *thisCookieDomain = NULL;
cookie *thisCookie;
struct list *cursor;
cookie_container_t *container;
cookie_t *thisCookie;
LPWSTR data, value;
WCHAR *ptr;
FILETIME expiry, create;
BOOL expired = FALSE, update_persistent = FALSE;
DWORD cookie_flags = 0;
TRACE("%s %s %s=%s %x\n", debugstr_w(domain), debugstr_w(path), debugstr_w(cookie_name), debugstr_w(cookie_data), flags);
value = data = heap_strdupW(cookie_data);
if (!data)
{
......@@ -935,25 +973,12 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
load_persistent_cookie(domain, path);
LIST_FOR_EACH(cursor, &domain_list)
{
thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry);
if (COOKIE_matchDomain(domain, path, thisCookieDomain, FALSE))
break;
thisCookieDomain = NULL;
}
if (!thisCookieDomain)
{
if (!expired)
thisCookieDomain = COOKIE_addDomain(domain, path);
else
{
heap_free(data);
if (value != data) heap_free(value);
LeaveCriticalSection(&cookie_cs);
return COOKIE_STATE_ACCEPT;
}
container = get_cookie_container(domain, path, !expired);
if(!container) {
heap_free(data);
if (value != data) heap_free(value);
LeaveCriticalSection(&cookie_cs);
return COOKIE_STATE_ACCEPT;
}
if(!expiry.dwLowDateTime && !expiry.dwHighDateTime)
......@@ -961,7 +986,7 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
else
update_persistent = TRUE;
if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name)))
if ((thisCookie = find_cookie(container, cookie_name)))
{
if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
WARN("An attempt to override httponly cookie\n");
......@@ -973,23 +998,29 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
if (!(thisCookie->flags & INTERNET_COOKIE_IS_SESSION))
update_persistent = TRUE;
COOKIE_deleteCookie(thisCookie, FALSE);
delete_cookie(thisCookie);
}
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
debugstr_w(value), debugstr_w(thisCookieDomain->lpCookieDomain),debugstr_w(thisCookieDomain->lpCookiePath));
debugstr_w(value), debugstr_w(container->domain->domain),debugstr_w(container->path));
if (!expired && !COOKIE_addCookie(thisCookieDomain, cookie_name, value, expiry, create, cookie_flags))
{
heap_free(data);
if (value != data) heap_free(value);
LeaveCriticalSection(&cookie_cs);
return COOKIE_STATE_UNKNOWN;
if (!expired) {
cookie_t *new_cookie;
new_cookie = alloc_cookie(cookie_name, value, expiry, create, cookie_flags);
if(!new_cookie) {
heap_free(data);
if (value != data) heap_free(value);
LeaveCriticalSection(&cookie_cs);
return COOKIE_STATE_UNKNOWN;
}
add_cookie(container, new_cookie);
}
heap_free(data);
if (value != data) heap_free(value);
if (!update_persistent || save_persistent_cookie(thisCookieDomain))
if (!update_persistent || save_persistent_cookie(container))
{
LeaveCriticalSection(&cookie_cs);
return COOKIE_STATE_ACCEPT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment