Andrew Eikum : shlwapi: Handle URL_WININET_COMPATIBILITY flag in UrlCanonicalize.

Alexandre Julliard julliard at winehq.org
Tue Oct 12 11:26:58 CDT 2010


Module: wine
Branch: master
Commit: 6525d89c95e6ae28eb8f6635a7fb9cb756cc1c97
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6525d89c95e6ae28eb8f6635a7fb9cb756cc1c97

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Oct 11 11:17:35 2010 -0500

shlwapi: Handle URL_WININET_COMPATIBILITY flag in UrlCanonicalize.

---

 dlls/shlwapi/tests/url.c      |   21 +++++++++++++++++
 dlls/shlwapi/url.c            |   50 ++++++++++++++++++++++++++++++++++------
 dlls/wininet/tests/internet.c |    2 +-
 3 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c
index cf74177..febe23d 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 c808a2f..04e80f9 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 4da9c21..54fd229 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 */




More information about the wine-cvs mailing list