Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
4707b448
Commit
4707b448
authored
Jul 14, 2014
by
Jacek Caban
Committed by
Alexandre Julliard
Jul 14, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wininet: Rewrite structs storing cookies to represent domains as a tree.
parent
ffec675b
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
301 additions
and
270 deletions
+301
-270
cookie.c
dlls/wininet/cookie.c
+301
-270
No files found.
dlls/wininet/cookie.c
View file @
4707b448
...
...
@@ -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
lpCookieN
ame
;
LPWSTR
lpCookieD
ata
;
WCHAR
*
n
ame
;
WCHAR
*
d
ata
;
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
->
lpCookieP
ath
,
cookie_url
,
sizeof
(
cookie_url
)
/
sizeof
(
cookie_url
[
0
])))
if
(
!
create_cookie_url
(
container
->
domain
->
domain
,
container
->
p
ath
,
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
->
lpCookieN
ame
);
dyn_buf
=
heap_strdupWtoA
(
cookie_container
->
n
ame
);
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
->
lpCookieD
ata
);
dyn_buf
=
heap_strdupWtoA
(
cookie_container
->
d
ata
);
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
->
lpCookieD
omain
);
dyn_buf
=
heap_strdupWtoA
(
container
->
domain
->
d
omain
);
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
->
lpCookieP
ath
);
dyn_buf
=
heap_strdupWtoA
(
container
->
p
ath
);
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
->
lpCookieP
ath
));
debugstr_w
(
value
),
debugstr_w
(
container
->
domain
->
domain
),
debugstr_w
(
container
->
p
ath
));
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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment