mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-04 15:44:52 +00:00
wininet: Properly handle output buffer size in InternetGetCookieW.
This commit is contained in:
parent
8f03c51e55
commit
0c02e35841
4 changed files with 57 additions and 31 deletions
|
@ -31,6 +31,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
@ -529,9 +530,10 @@ static void COOKIE_deleteDomain(cookie_domain *deadDomain)
|
|||
heap_free(deadDomain);
|
||||
}
|
||||
|
||||
BOOL get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD *size)
|
||||
DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD *size)
|
||||
{
|
||||
unsigned cnt = 0, len, domain_count = 0, cookie_count = 0;
|
||||
unsigned cnt = 0, len, name_len, domain_count = 0, cookie_count = 0;
|
||||
WCHAR *ptr = cookie_data;
|
||||
cookie_domain *domain;
|
||||
FILETIME tm;
|
||||
|
||||
|
@ -562,49 +564,62 @@ BOOL get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
|
|||
continue;
|
||||
}
|
||||
|
||||
if(!cookie_data) { /* return the size of the buffer required to lpdwSize */
|
||||
if (cookie_count)
|
||||
cnt += 2; /* '; ' */
|
||||
cnt += strlenW(cookie_iter->lpCookieName);
|
||||
if ((len = strlenW(cookie_iter->lpCookieData))) {
|
||||
cnt += 1; /* = */
|
||||
cnt += len;
|
||||
}
|
||||
}else {
|
||||
static const WCHAR szsc[] = { ';',' ',0 };
|
||||
static const WCHAR szname[] = { '%','s',0 };
|
||||
static const WCHAR szdata[] = { '=','%','s',0 };
|
||||
|
||||
if (cookie_count) cnt += snprintfW(cookie_data + cnt, *size - cnt, szsc);
|
||||
cnt += snprintfW(cookie_data + cnt, *size - cnt, szname, cookie_iter->lpCookieName);
|
||||
|
||||
if (cookie_iter->lpCookieData[0])
|
||||
cnt += snprintfW(cookie_data + cnt, *size - cnt, szdata, cookie_iter->lpCookieData);
|
||||
|
||||
TRACE("Cookie: %s\n", debugstr_w(cookie_data));
|
||||
if (cookie_count)
|
||||
cnt += 2; /* '; ' */
|
||||
cnt += name_len = strlenW(cookie_iter->lpCookieName);
|
||||
if ((len = strlenW(cookie_iter->lpCookieData))) {
|
||||
cnt += 1; /* = */
|
||||
cnt += len;
|
||||
}
|
||||
|
||||
if(ptr) {
|
||||
if(*size > cnt) {
|
||||
if(cookie_count) {
|
||||
*ptr++ = ';';
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
|
||||
memcpy(ptr, cookie_iter->lpCookieName, name_len*sizeof(WCHAR));
|
||||
ptr += name_len;
|
||||
|
||||
if(len) {
|
||||
*ptr++ = '=';
|
||||
memcpy(ptr, cookie_iter->lpCookieData, 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++;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&cookie_cs);
|
||||
|
||||
if (!domain_count) {
|
||||
if(ptr)
|
||||
*ptr = 0;
|
||||
|
||||
if (!cnt) {
|
||||
TRACE("no cookies found for %s\n", debugstr_w(host));
|
||||
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||
return FALSE;
|
||||
return ERROR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
if(!cookie_data) {
|
||||
if(!cookie_data || !ptr) {
|
||||
*size = (cnt + 1) * sizeof(WCHAR);
|
||||
TRACE("returning %u\n", *size);
|
||||
return TRUE;
|
||||
return cookie_data ? ERROR_INSUFFICIENT_BUFFER : ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
*size = cnt + 1;
|
||||
|
||||
TRACE("Returning %u (from %u domains): %s\n", cnt, domain_count, debugstr_w(cookie_data));
|
||||
return cnt != 0;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -624,6 +639,7 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
|||
LPWSTR lpCookieData, LPDWORD lpdwSize)
|
||||
{
|
||||
WCHAR host[INTERNET_MAX_HOST_NAME_LENGTH], path[INTERNET_MAX_PATH_LENGTH];
|
||||
DWORD res;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), lpCookieData, lpdwSize);
|
||||
|
@ -641,7 +657,10 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return get_cookie(host, path, lpCookieData, lpdwSize);
|
||||
res = get_cookie(host, path, lpCookieData, lpdwSize);
|
||||
if(res != ERROR_SUCCESS)
|
||||
SetLastError(res);
|
||||
return res == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4008,7 +4008,7 @@ static void HTTP_InsertCookies(http_request_t *request)
|
|||
if(!host)
|
||||
return;
|
||||
|
||||
if(!get_cookie(host->lpszValue, request->path, NULL, &cookie_size))
|
||||
if(get_cookie(host->lpszValue, request->path, NULL, &cookie_size) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
size = sizeof(cookieW) + cookie_size * sizeof(WCHAR) + sizeof(szCrLf);
|
||||
|
|
|
@ -517,7 +517,7 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
|
|||
BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
|
||||
struct sockaddr *psa, socklen_t *sa_len) DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL get_cookie(const WCHAR*,const WCHAR*,WCHAR*,DWORD*) DECLSPEC_HIDDEN;
|
||||
DWORD get_cookie(const WCHAR*,const WCHAR*,WCHAR*,DWORD*) DECLSPEC_HIDDEN;
|
||||
BOOL set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
|
||||
|
||||
void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -426,6 +426,13 @@ static void test_complicated_cookie(void)
|
|||
ok(len == 19, "len = %u\n", len);
|
||||
ok(lstrlenW(wbuf) == 18, "strlenW(wbuf) = %u\n", lstrlenW(wbuf));
|
||||
|
||||
len = 10;
|
||||
memset(wbuf, 0xac, sizeof(wbuf));
|
||||
ret = InternetGetCookieW(testing_example_comW, NULL, wbuf, &len);
|
||||
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||
"InternetGetCookieW returned: %x(%u), expected ERROR_INSUFFICIENT_BUFFER\n", ret, GetLastError());
|
||||
ok(len == 38, "len = %u\n", len);
|
||||
|
||||
len = 1024;
|
||||
ret = InternetGetCookie("http://testing.example.com/foobar", NULL, buffer, &len);
|
||||
ok(ret == TRUE,"InternetGetCookie failed\n");
|
||||
|
|
Loading…
Reference in a new issue