From: Hans Leidekker hans@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57794 --- dlls/winhttp/request.c | 49 ++++++++++++++++++------------------ dlls/winhttp/tests/winhttp.c | 32 +++++++++++++++++++++-- 2 files changed, 55 insertions(+), 26 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index cd3e4200e73..d3ec53274cd 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -2622,9 +2622,9 @@ static DWORD read_reply( struct request *request ) { char buffer[MAX_REPLY_LEN]; DWORD ret, buflen, len, offset, crlf_len = 2; /* lstrlenW(crlf) */ - char *status_code, *status_text; + const char *status_text, *ptr; WCHAR *versionW, *status_textW, *raw_headers; - WCHAR status_codeW[4]; /* sizeof("nnn") */ + WCHAR status_code[4]; /* sizeof("nnn") */
if (!request->netconn) return ERROR_WINHTTP_INCORRECT_HANDLE_STATE;
@@ -2634,34 +2634,35 @@ static DWORD read_reply( struct request *request ) if ((ret = read_line( request, buffer, &buflen ))) return ret;
/* first line should look like 'HTTP/1.x nnn OK' where nnn is the status code */ - if (!(status_code = strchr( buffer, ' ' ))) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE; - status_code++; - if (!(status_text = strchr( status_code, ' ' ))) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE; - if ((len = status_text - status_code) != sizeof("nnn") - 1) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE; - status_text++; - - TRACE("version [%s] status code [%s] status text [%s]\n", - debugstr_an(buffer, status_code - buffer - 1), - debugstr_an(status_code, len), - debugstr_a(status_text)); - - } while (!memcmp( status_code, "100", len )); /* ignore "100 Continue" responses */ - - /* we rely on the fact that the protocol is ascii */ - MultiByteToWideChar( CP_ACP, 0, status_code, len, status_codeW, len ); - status_codeW[len] = 0; - if ((ret = process_header( request, L"Status", status_codeW, + if (!(ptr = strchr( buffer, ' ' ))) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE; + len = ptr - buffer; + + while (*ptr == ' ') ptr++; + if (!isdigit( ptr[0] ) || !isdigit( ptr[1] ) || !isdigit( ptr[2] )) return ERROR_WINHTTP_INVALID_SERVER_RESPONSE; + status_code[0] = *ptr++; + status_code[1] = *ptr++; + status_code[2] = *ptr++; + status_code[3] = 0; + + while (*ptr == ' ') ptr++; + status_text = ptr; + + TRACE( "version [%s] status code [%s] status text [%s]\n", debugstr_an(buffer, len), + debugstr_w(status_code), debugstr_a(status_text) ); + + } while (!wcscmp( status_code, L"100" )); /* ignore "100 Continue" responses */ + + if ((ret = process_header( request, L"Status", status_code, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE, FALSE ))) return ret;
- len = status_code - buffer; - if (!(versionW = malloc( len * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; - MultiByteToWideChar( CP_ACP, 0, buffer, len - 1, versionW, len -1 ); - versionW[len - 1] = 0; + if (!(versionW = malloc( (len + 1) * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; + MultiByteToWideChar( CP_ACP, 0, buffer, len, versionW, len ); + versionW[len] = 0;
free( request->version ); request->version = versionW;
- len = buflen - (status_text - buffer); + len = strlen( status_text ) + 1; if (!(status_textW = malloc( len * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; MultiByteToWideChar( CP_ACP, 0, status_text, len, status_textW, len );
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index 1588a2b1261..00c05caaa5a 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -2202,7 +2202,7 @@ static const char okmsg[] = "\r\n";
static const char okmsg_length0[] = -"HTTP/1.1 200 OK\r\n" +"HTTP/1.1 200 OK\r\n" "Server: winetest\r\n" "Content-length: 0\r\n" "\r\n"; @@ -2298,6 +2298,10 @@ static const char badreplyheadermsg[] = "OkHdr: ok\r\n" "\r\n";
+static const char nostatustext[] = +"HTTP/1.1 200\r\n" +"\r\n"; + static const char proxy_pac[] = "function FindProxyForURL(url, host) {\r\n" " url = url.replace(/[:/]/g, '_');\r\n" @@ -2610,6 +2614,12 @@ static DWORD CALLBACK server_thread(LPVOID param) r = server_receive_request(c, buffer, sizeof(buffer)); ok(!r, "got %d, buffer[0] %d.\n", r, buffer[0] ); } + if (strstr(buffer, "GET /nostatustext")) + { + send(c, nostatustext, sizeof nostatustext - 1, 0); + r = server_receive_request(c, buffer, sizeof(buffer)); + ok(!r, "got %d, buffer[0] %d.\n", r, buffer[0] ); + } shutdown(c, 2); closesocket(c); c = -1; @@ -3128,7 +3138,8 @@ static void test_large_data_authentication(int port) static void test_no_headers(int port) { HINTERNET ses, con, req; - DWORD error; + DWORD error, size; + WCHAR buf[10]; BOOL ret;
ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); @@ -3155,6 +3166,23 @@ static void test_no_headers(int port) ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %lu\n", error); }
+ WinHttpCloseHandle(req); + + req = WinHttpOpenRequest(con, NULL, L"/nostatustext", NULL, NULL, NULL, 0); + ok(req != NULL, "failed to open a request %lu\n", GetLastError()); + + ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); + ok(ret, "got %lu\n", GetLastError()); + + ret = WinHttpReceiveResponse(req, NULL); + ok(ret, "got %lu\n", GetLastError()); + + memset(buf, 0xcc, sizeof(buf)); + size = sizeof(buf); + ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_TEXT, NULL, buf, &size, NULL); + ok(ret, "got %lu\n", GetLastError()); + ok(!buf[0], "got %x\n", buf[0]); + WinHttpCloseHandle(req); WinHttpCloseHandle(con); WinHttpCloseHandle(ses);