Module: wine Branch: master Commit: 41cf9a8372e698ecfa81254fd9ed67459607c3d6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=41cf9a8372e698ecfa81254fd9...
Author: Hans Leidekker hans@codeweavers.com Date: Mon Jun 15 17:32:25 2015 +0200
winhttp: Improve parsing of cookie values.
---
dlls/winhttp/cookie.c | 53 ++++++++++---------- dlls/winhttp/tests/winhttp.c | 117 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 26 deletions(-)
diff --git a/dlls/winhttp/cookie.c b/dlls/winhttp/cookie.c index 6e104b2..4bf0808 100644 --- a/dlls/winhttp/cookie.c +++ b/dlls/winhttp/cookie.c @@ -134,22 +134,14 @@ static cookie_t *parse_cookie( const WCHAR *string ) const WCHAR *p; int len;
- if (!(p = strchrW( string, '=' ))) - { - WARN("no '=' in %s\n", debugstr_w(string)); - return NULL; - } - if (p == string) - { - WARN("empty cookie name in %s\n", debugstr_w(string)); - return NULL; - } + if (!(p = strchrW( string, '=' ))) p = string + strlenW( string ); + len = p - string; + while (len && string[len - 1] == ' ') len--; + if (!len) return NULL;
if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL; - list_init( &cookie->entry );
- len = p - string; if (!(cookie->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) { heap_free( cookie ); @@ -158,18 +150,20 @@ static cookie_t *parse_cookie( const WCHAR *string ) memcpy( cookie->name, string, len * sizeof(WCHAR) ); cookie->name[len] = 0;
- p++; /* skip '=' */ - while (*p == ' ') p++; - - len = strlenW( p ); - if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + if (*p++ == '=') { - free_cookie( cookie ); - return NULL; - } - memcpy( cookie->value, p, len * sizeof(WCHAR) ); - cookie->value[len] = 0; + while (*p && *p == ' ') p++; + len = strlenW( p ); + while (len && p[len - 1] == ' ') len--;
+ if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + free_cookie( cookie ); + return NULL; + } + memcpy( cookie->value, p, len * sizeof(WCHAR) ); + cookie->value[len] = 0; + } return cookie; }
@@ -259,14 +253,21 @@ BOOL add_cookie_headers( request_t *request )
if (strstrW( request->path, cookie->path ) == request->path) { - const WCHAR format[] = {'C','o','o','k','i','e',':',' ','%','s','=','%','s',0}; - int len; + const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '}; + int len, len_cookie = sizeof(cookieW) / sizeof(cookieW[0]), len_name = strlenW( cookie->name ); WCHAR *header;
- len = strlenW( cookie->name ) + strlenW( format ) + strlenW( cookie->value ); + len = len_cookie + len_name; + if (cookie->value) len += strlenW( cookie->value ) + 1; if (!(header = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
- sprintfW( header, format, cookie->name, cookie->value ); + memcpy( header, cookieW, len_cookie * sizeof(WCHAR) ); + strcpyW( header + len_cookie, cookie->name ); + if (cookie->value) + { + header[len_cookie + len_name] = '='; + strcpyW( header + len_cookie + len_name + 1, cookie->value ); + }
TRACE("%s\n", debugstr_w(header)); add_request_headers( request, header, len, WINHTTP_ADDREQ_FLAG_ADD ); diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index 3860461..10a3f06 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -1799,6 +1799,15 @@ static const char okmsg[] = "Server: winetest\r\n" "\r\n";
+static const char notokmsg[] = +"HTTP/1.1 400 Bad Request\r\n" +"\r\n"; + +static const char cookiemsg[] = +"HTTP/1.1 200 OK\r\n" +"Set-Cookie: name = value \r\n" +"\r\n"; + static const char nocontentmsg[] = "HTTP/1.1 204 No Content\r\n" "Server: winetest\r\n" @@ -1917,6 +1926,16 @@ static DWORD CALLBACK server_thread(LPVOID param) send(c, headmsg, sizeof headmsg - 1, 0); continue; } + if (strstr(buffer, "GET /cookie2")) + { + if (strstr(buffer, "Cookie: name=value\r\n")) send(c, okmsg, sizeof(okmsg) - 1, 0); + else send(c, notokmsg, sizeof(notokmsg) - 1, 0); + } + else if (strstr(buffer, "GET /cookie")) + { + if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0); + else send(c, notokmsg, sizeof(notokmsg) - 1, 0); + } if (strstr(buffer, "GET /quit")) { send(c, okmsg, sizeof okmsg - 1, 0); @@ -2503,6 +2522,103 @@ static void test_multiple_reads(int port) WinHttpCloseHandle(ses); }
+static void test_cookies( int port ) +{ + static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0}; + static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0}; + HINTERNET ses, con, req; + DWORD status, size; + BOOL ret; + + ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 ); + ok( ses != NULL, "failed to open session %u\n", GetLastError() ); + + con = WinHttpConnect( ses, localhostW, port, 0 ); + ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); + + req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 ); + ok( req != NULL, "failed to open a request %u\n", GetLastError() ); + + ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); + ok( ret, "failed to send request %u\n", GetLastError() ); + + ret = WinHttpReceiveResponse( req, NULL ); + ok( ret, "failed to receive response %u\n", GetLastError() ); + + status = 0xdeadbeef; + size = sizeof(status); + ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); + ok( ret, "failed to query status code %u\n", GetLastError() ); + ok( status == 200, "request failed unexpectedly %u\n", status ); + + WinHttpCloseHandle( req ); + + req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); + ok( req != NULL, "failed to open a request %u\n", GetLastError() ); + + ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); + ok( ret, "failed to send request %u\n", GetLastError() ); + + ret = WinHttpReceiveResponse( req, NULL ); + ok( ret, "failed to receive response %u\n", GetLastError() ); + + status = 0xdeadbeef; + size = sizeof(status); + ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); + ok( ret, "failed to query status code %u\n", GetLastError() ); + ok( status == 200, "request failed unexpectedly %u\n", status ); + + WinHttpCloseHandle( req ); + WinHttpCloseHandle( con ); + + con = WinHttpConnect( ses, localhostW, port, 0 ); + ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); + + req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); + ok( req != NULL, "failed to open a request %u\n", GetLastError() ); + + ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); + ok( ret, "failed to send request %u\n", GetLastError() ); + + ret = WinHttpReceiveResponse( req, NULL ); + ok( ret, "failed to receive response %u\n", GetLastError() ); + + status = 0xdeadbeef; + size = sizeof(status); + ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); + ok( ret, "failed to query status code %u\n", GetLastError() ); + ok( status == 200, "request failed unexpectedly %u\n", status ); + + WinHttpCloseHandle( req ); + WinHttpCloseHandle( con ); + WinHttpCloseHandle( ses ); + + ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 ); + ok( ses != NULL, "failed to open session %u\n", GetLastError() ); + + con = WinHttpConnect( ses, localhostW, port, 0 ); + ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); + + req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); + ok( req != NULL, "failed to open a request %u\n", GetLastError() ); + + ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); + ok( ret, "failed to send request %u\n", GetLastError() ); + + ret = WinHttpReceiveResponse( req, NULL ); + ok( ret, "failed to receive response %u\n", GetLastError() ); + + status = 0xdeadbeef; + size = sizeof(status); + ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); + ok( ret, "failed to query status code %u\n", GetLastError() ); + ok( status == 400, "request failed unexpectedly %u\n", status ); + + WinHttpCloseHandle( req ); + WinHttpCloseHandle( con ); + WinHttpCloseHandle( ses ); +} + static void test_connection_info( int port ) { static const WCHAR basicW[] = {'/','b','a','s','i','c',0}; @@ -3478,6 +3594,7 @@ START_TEST (winhttp) test_basic_authentication(si.port); test_bad_header(si.port); test_multiple_reads(si.port); + test_cookies(si.port);
/* send the basic request again to shutdown the server thread */ test_basic_request(si.port, NULL, quitW);