diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index cf741777618..febe23d56e6 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -123,6 +123,9 @@ static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = { {"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example", FALSE}, {"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar", FALSE}, {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar", FALSE}, + {"http://www.winehq.org", 0, S_OK, "http://www.winehq.org/", FALSE}, + {"http:///www.winehq.org", 0, S_OK, "http:///www.winehq.org", FALSE}, + {"http:////www.winehq.org", 0, S_OK, "http:////www.winehq.org", FALSE}, {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar", FALSE}, {"file:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar", FALSE}, {"file:///c:/tests/foo%20bar", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE}, @@ -137,6 +140,24 @@ static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = { {"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\\\tests\\foo bar", FALSE}, {"file:///c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo bar", FALSE}, {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "file:///c:/tests/foo bar", FALSE}, + {"file:///c:\\tests\\foobar", 0, S_OK, "file:///c:/tests/foobar", FALSE}, + {"file:///c:\\tests\\foobar", URL_WININET_COMPATIBILITY, S_OK, "file://c:\\tests\\foobar", FALSE}, + {"file://home/user/file", 0, S_OK, "file://home/user/file", FALSE}, + {"file:///home/user/file", 0, S_OK, "file:///home/user/file", FALSE}, + {"file:////home/user/file", 0, S_OK, "file://home/user/file", FALSE}, + {"file://home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE}, + {"file:///home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\home\\user\\file", FALSE}, + {"file:////home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE}, + {"file://///home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE}, + {"file://C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE}, + {"file://C:/user/file/../asdf", 0, S_OK, "file:///C:/user/asdf", FALSE}, + {"file:///C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE}, + {"file:////C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE}, + {"file://C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE}, + {"file:///C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE}, + {"file:////C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE}, + {"http:///www.winehq.org", 0, S_OK, "http:///www.winehq.org", FALSE}, + {"http:///www.winehq.org", URL_WININET_COMPATIBILITY, S_OK, "http:///www.winehq.org", FALSE}, {"http://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/site/about", FALSE}, {"file_://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "file_://www.winehq.org/site/about", FALSE}, {"c:\\dir\\file", 0, S_OK, "file:///c:/dir/file", FALSE}, diff --git a/dlls/shlwapi/url.c b/dlls/shlwapi/url.c index c808a2f5f7a..04e80f971af 100644 --- a/dlls/shlwapi/url.c +++ b/dlls/shlwapi/url.c @@ -276,6 +276,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, LPWSTR lpszUrlCpy, url, wk2, mp, mp2; INT state; DWORD nByteLen, nLen, nWkLen; + BOOL is_file_url; WCHAR slash = '\0'; static const WCHAR wszFile[] = {'f','i','l','e',':'}; @@ -318,14 +319,13 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, return E_OUTOFMEMORY; } + is_file_url = !strncmpW(wszFile, url, sizeof(wszFile)/sizeof(WCHAR)); + if ((nByteLen >= sizeof(wszHttp) && - !memcmp(wszHttp, url, sizeof(wszHttp))) || - (nByteLen >= sizeof(wszFile) && - !memcmp(wszFile, url, sizeof(wszFile)))) + !memcmp(wszHttp, url, sizeof(wszHttp))) || is_file_url) slash = '/'; - if((dwFlags & URL_FILE_USE_PATHURL) && nByteLen >= sizeof(wszFile) - && !memcmp(wszFile, url, sizeof(wszFile))) + if((dwFlags & (URL_FILE_USE_PATHURL | URL_WININET_COMPATIBILITY)) && is_file_url) slash = '\\'; if(nByteLen >= sizeof(wszRes) && !memcmp(wszRes, url, sizeof(wszRes))) { @@ -351,7 +351,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, if(url[1] == ':') { /* Assume path */ memcpy(wk2, wszFilePrefix, sizeof(wszFilePrefix)); wk2 += sizeof(wszFilePrefix)/sizeof(WCHAR); - if (dwFlags & URL_FILE_USE_PATHURL) + if (dwFlags & (URL_FILE_USE_PATHURL | URL_WININET_COMPATIBILITY)) { slash = '\\'; --wk2; @@ -359,6 +359,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, else dwFlags |= URL_ESCAPE_UNSAFE; state = 5; + is_file_url = TRUE; } while (*wk1) { @@ -379,14 +380,47 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, if (*wk1 != '/') {state = 6; break;} *wk2++ = *wk1++; if((dwFlags & URL_FILE_USE_PATHURL) && nByteLen >= sizeof(wszLocalhost) - && !strncmpW(wszFile, url, sizeof(wszFile)/sizeof(WCHAR)) + && is_file_url && !memcmp(wszLocalhost, wk1, sizeof(wszLocalhost))){ wk1 += sizeof(wszLocalhost)/sizeof(WCHAR); while(*wk1 == '\\' && (dwFlags & URL_FILE_USE_PATHURL)) wk1++; } - if(*wk1 == '/' && (dwFlags & URL_FILE_USE_PATHURL)) + + if(*wk1 == '/' && (dwFlags & URL_FILE_USE_PATHURL)){ wk1++; + }else if(is_file_url){ + const WCHAR *body = wk1; + + while(*body == '/') + ++body; + + if(isalnumW(*body) && *(body+1) == ':'){ + if(!(dwFlags & (URL_WININET_COMPATIBILITY | URL_FILE_USE_PATHURL))){ + if(slash) + *wk2++ = slash; + else + *wk2++ = '/'; + } + }else{ + if(dwFlags & URL_WININET_COMPATIBILITY){ + if(*wk1 == '/' && *(wk1+1) != '/'){ + *wk2++ = '\\'; + }else{ + *wk2++ = '\\'; + *wk2++ = '\\'; + } + }else{ + if(*wk1 == '/' && *(wk1+1) != '/'){ + if(slash) + *wk2++ = slash; + else + *wk2++ = '/'; + } + } + } + wk1 = body; + } state = 4; break; case 3: diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 4da9c218839..54fd229245d 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -103,7 +103,7 @@ static void test_InternetCanonicalizeUrlA(void) res = InternetCanonicalizeUrlA("file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", buffer, &dwSize, ICU_DECODE | ICU_NO_ENCODE); ok(res, "InternetCanonicalizeUrlA failed %u\n", GetLastError()); ok(dwSize == lstrlenA(buffer), "got %d expected %d\n", dwSize, lstrlenA(buffer)); - todo_wine ok(!lstrcmpA("file://C:\\Program Files\\Atmel\\AVR Tools\\STK500\\STK500.xml", buffer), + ok(!lstrcmpA("file://C:\\Program Files\\Atmel\\AVR Tools\\STK500\\STK500.xml", buffer), "got %s expected 'file://C:\\Program Files\\Atmel\\AVR Tools\\STK500\\STK500.xml'\n", buffer); /* buffer is larger as the required size */