Based on a patch by Etaash Mathamsetty.
From: Hans Leidekker hans@codeweavers.com
Based on a patch by Etaash Mathamsetty. --- dlls/wininet/http.c | 6 +++--- dlls/wininet/tests/internet.c | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 38f6575c1fd..cc9b89d1129 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -4521,7 +4521,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft) /* asctime() doesn't report a timezone, but some web servers do, so accept * with or without GMT. */ - if (*ptr && wcscmp(ptr, L"GMT")) + if (*ptr && (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))) { ERR("unexpected timezone %s\n", debugstr_w(ptr)); return FALSE; @@ -4598,7 +4598,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft) while (iswspace(*ptr)) ptr++;
- if (wcscmp(ptr, L"GMT")) + if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC")) { ERR("unexpected time zone %s\n", debugstr_w(ptr)); return FALSE; @@ -4715,7 +4715,7 @@ static BOOL HTTP_ParseRfc850Date(LPCWSTR value, FILETIME *ft) while (iswspace(*ptr)) ptr++;
- if (wcscmp(ptr, L"GMT")) + if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC")) { ERR("unexpected time zone %s\n", debugstr_w(ptr)); return FALSE; diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index c432de9e488..f2579c4993a 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1116,9 +1116,11 @@ static void test_InternetTimeToSystemTime(void) test_data[] = { { "Fri, 07 Jan 2005 12:06:35 GMT", &expect1, TRUE }, + { "Fri, 07 Jan 2005 12:06:35 UTC", &expect1, TRUE }, { " fri, 7 jan 2005 12 06 35", &expect1, TRUE }, { "Fri, 07-01-2005 12:06:35", &expect1, TRUE }, { "5, 07-01-2005 12:06:35 GMT", &expect1, TRUE }, + { "5, 07-01-2005 12:06:35 UTC", &expect1, TRUE }, { "5, 07-01-2005 12:06:35 GMT;", &expect1, TRUE }, { "5, 07-01-2005 12:06:35 GMT123", &expect1, TRUE }, { "2, 11 01 2022 11 13 05", &expect2, TRUE }, @@ -1126,6 +1128,9 @@ static void test_InternetTimeToSystemTime(void) { "2, 11*01/2022 11+13=05", &expect2, TRUE }, { "2, 11-Jan-2022 11:13:05", &expect2, TRUE }, { "Fr", NULL, FALSE }, + { "Fri Jan 7 12:06:35 2005", &expect1, TRUE, TRUE }, + { "Fri Jan 7 12:06:35 2005 GMT", &expect1, TRUE, TRUE }, + { "Fri Jan 7 12:06:35 2005 UTC", &expect1, TRUE, TRUE }, };
ret = pInternetTimeToSystemTimeA(NULL, NULL, 0);
From: Hans Leidekker hans@codeweavers.com
The current code calls mktime() which interprets its argument as local time while these values are assumed to be in UTC. --- dlls/wininet/http.c | 37 ++++++++--------- dlls/wininet/tests/http.c | 25 +++++++++++- dlls/wininet/utility.c | 86 --------------------------------------- 3 files changed, 40 insertions(+), 108 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index cc9b89d1129..92417714fac 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -3886,26 +3886,23 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, } else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer) { - time_t tmpTime; - struct tm tmpTM; - SYSTEMTIME *STHook; - - tmpTime = ConvertTimeString(lphttpHdr->lpszValue); - - tmpTM = *gmtime(&tmpTime); - STHook = (SYSTEMTIME *)lpBuffer; - STHook->wDay = tmpTM.tm_mday; - STHook->wHour = tmpTM.tm_hour; - STHook->wMilliseconds = 0; - STHook->wMinute = tmpTM.tm_min; - STHook->wDayOfWeek = tmpTM.tm_wday; - STHook->wMonth = tmpTM.tm_mon + 1; - STHook->wSecond = tmpTM.tm_sec; - STHook->wYear = 1900+tmpTM.tm_year; - - TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n", - STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek, - STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds); + SYSTEMTIME st; + + if (!InternetTimeToSystemTimeW(lphttpHdr->lpszValue, &st, 0)) + { + LeaveCriticalSection( &request->headers_section ); + return ERROR_HTTP_INVALID_HEADER; + } + if (*lpdwBufferLength < sizeof(st)) + { + *lpdwBufferLength = sizeof(st); + LeaveCriticalSection( &request->headers_section ); + return ERROR_INSUFFICIENT_BUFFER; + } + TRACE(" returning time: %04u/%02u/%02u - %u - %02u:%02u:%02u.%02u\n", + st.wYear, st.wMonth, st.wDay, st.wDayOfWeek, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + memcpy(lpBuffer, &st, sizeof(st)); + *lpdwBufferLength = sizeof(st); } else if (lphttpHdr->lpszValue) { diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index bc18986c69f..5c8f85f4d2a 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -2412,6 +2412,7 @@ static const char okmsg2[] = "Content-Length: 0\r\n" "Set-Cookie: one\r\n" "Set-Cookie: two\r\n" +"Last-Modified: Mon, 01 Dec 2008 13:44:34 UTC\r\n" "\r\n";
static DWORD64 content_length; @@ -4566,9 +4567,11 @@ static void test_head_request(int port)
static void test_HttpQueryInfo(int port) { + static const SYSTEMTIME expect = {2008, 12, 1, 1, 13, 44, 34}; test_request_t req; DWORD size, index, error; char buffer[1024]; + SYSTEMTIME st; BOOL ret;
open_simple_request(&req, "localhost", port, NULL, "/testD"); @@ -4589,9 +4592,27 @@ static void test_HttpQueryInfo(int port) ok(index == 1, "expected 1 got %lu\n", index);
index = 0; - size = sizeof(buffer); - ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index); + size = 0; + ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); + ok(size == sizeof(st), "got %lu\n", size); + + index = 0; + size = sizeof(st) + 1; + memset(&st, 0, sizeof(st)); + ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index); + ok(ret, "HttpQueryInfo failed %lu\n", GetLastError()); + ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n"); + ok(size == sizeof(st), "got %lu\n", size); + ok(index == 1, "expected 1 got %lu\n", index); + + index = 0; + size = sizeof(st); + memset(&st, 0, sizeof(st)); + ret = HttpQueryInfoA(req.request, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index); ok(ret, "HttpQueryInfo failed %lu\n", GetLastError()); + ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n"); + ok(size == sizeof(st), "got %lu\n", size); ok(index == 1, "expected 1 got %lu\n", index);
index = 0; diff --git a/dlls/wininet/utility.c b/dlls/wininet/utility.c index a9a0b9f8d94..8d621d39c7d 100644 --- a/dlls/wininet/utility.c +++ b/dlls/wininet/utility.c @@ -39,92 +39,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
-#define TIME_STRING_LEN 30 - -time_t ConvertTimeString(LPCWSTR asctime) -{ - WCHAR tmpChar[TIME_STRING_LEN]; - WCHAR *tmpChar2; - struct tm t; - int timelen = lstrlenW(asctime); - - if(!timelen) - return 0; - - /* FIXME: the atoiWs below rely on that tmpChar is \0 padded */ - memset( tmpChar, 0, sizeof(tmpChar) ); - lstrcpynW(tmpChar, asctime, TIME_STRING_LEN); - - /* Assert that the string is the expected length */ - if (lstrlenW(asctime) >= TIME_STRING_LEN) FIXME("\n"); - - /* Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure - * We assume the time is in this format - * and divide it into easy to swallow chunks - */ - tmpChar[3]='\0'; - tmpChar[7]='\0'; - tmpChar[11]='\0'; - tmpChar[16]='\0'; - tmpChar[19]='\0'; - tmpChar[22]='\0'; - tmpChar[25]='\0'; - - memset( &t, 0, sizeof(t) ); - t.tm_year = wcstol(tmpChar+12, NULL, 10) - 1900; - t.tm_mday = wcstol(tmpChar+5, NULL, 10); - t.tm_hour = wcstol(tmpChar+17, NULL, 10); - t.tm_min = wcstol(tmpChar+20, NULL, 10); - t.tm_sec = wcstol(tmpChar+23, NULL, 10); - - /* and month */ - tmpChar2 = tmpChar + 8; - switch(tmpChar2[2]) - { - case 'n': - if(tmpChar2[1]=='a') - t.tm_mon = 0; - else - t.tm_mon = 5; - break; - case 'b': - t.tm_mon = 1; - break; - case 'r': - if(tmpChar2[1]=='a') - t.tm_mon = 2; - else - t.tm_mon = 3; - break; - case 'y': - t.tm_mon = 4; - break; - case 'l': - t.tm_mon = 6; - break; - case 'g': - t.tm_mon = 7; - break; - case 'p': - t.tm_mon = 8; - break; - case 't': - t.tm_mon = 9; - break; - case 'v': - t.tm_mon = 10; - break; - case 'c': - t.tm_mon = 11; - break; - default: - FIXME("\n"); - } - - return mktime(&t); -} - - BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str) { ADDRINFOW *res, hints;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149676
Your paranoid android.
=== debian11b (64 bit WoW report) ===
Report validation errors: d3d11:d3d11 has no test summary line (early exit of the main process?) d3d11:d3d11 has unaccounted for todo messages d3d11:d3d11 returned a non-zero exit code despite reporting no failures
This merge request was approved by Jacek Caban.