Andrew Eikum : shlwapi: Improve error handling in UrlGetPart.

Alexandre Julliard julliard at winehq.org
Mon Mar 15 12:19:39 CDT 2010


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Fri Mar 12 17:22:43 2010 -0600

shlwapi: Improve error handling in UrlGetPart.

---

 dlls/shlwapi/tests/url.c |   51 +++++++++++++++++++++++++++++++--
 dlls/shlwapi/url.c       |   69 ++++++++++++++++++++++++++++++---------------
 dlls/urlmon/sec_mgr.c    |   15 ++++++----
 3 files changed, 102 insertions(+), 33 deletions(-)

diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c
index 31df64e..944d679 100644
--- a/dlls/shlwapi/tests/url.c
+++ b/dlls/shlwapi/tests/url.c
@@ -542,6 +542,14 @@ static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const
   HRESULT res;
   DWORD dwSize;
 
+  dwSize = 1;
+  res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags);
+  ok(res == E_POINTER, "UrlGetPart for \"%s\" gave: 0x%08x\n", szUrl, res);
+  ok(dwSize == strlen(szExpected)+1 ||
+          (*szExpected == '?' && dwSize == strlen(szExpected)),
+          "UrlGetPart for \"%s\" gave size: %d, expected: %d\n",
+          szUrl, dwSize, (*szExpected == '?' ? strlen(szExpected) : strlen(szExpected) + 1));
+
   dwSize = INTERNET_MAX_URL_LENGTH;
   res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags);
   ok(res == S_OK,
@@ -575,6 +583,7 @@ static void test_UrlGetPart(void)
 {
   const char* file_url = "file://h o s t/c:/windows/file";
   const char* http_url = "http://user:pass 123 at www.wine hq.org";
+  const char* res_url = "res://some.dll/find.dlg";
   const char* about_url = "about:blank";
 
   CHAR szPart[INTERNET_MAX_URL_LENGTH];
@@ -586,20 +595,38 @@ static void test_UrlGetPart(void)
     return;
   }
 
+  res = pUrlGetPartA(NULL, NULL, NULL, URL_PART_SCHEME, 0);
+  ok(res == E_INVALIDARG, "null params gave: 0x%08x\n", res);
+
+  res = pUrlGetPartA(NULL, szPart, &dwSize, URL_PART_SCHEME, 0);
+  ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res);
+
+  res = pUrlGetPartA(res_url, NULL, &dwSize, URL_PART_SCHEME, 0);
+  ok(res == E_INVALIDARG, "null szPart gave: 0x%08x\n", res);
+
+  res = pUrlGetPartA(res_url, szPart, NULL, URL_PART_SCHEME, 0);
+  ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res);
+
+  dwSize = 0;
+  szPart[0]='x'; szPart[1]=0;
+  res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
+  ok(res == E_INVALIDARG, "UrlGetPartA(*pcchOut = 0) returned %08X\n", res);
+  ok(szPart[0] == 'x' && szPart[1] == 0, "UrlGetPartA(*pcchOut = 0) modified szPart: \"%s\"\n", szPart);
+  ok(dwSize == 0, "dwSize = %d\n", dwSize);
+
   dwSize = sizeof szPart;
   szPart[0]='x'; szPart[1]=0;
   res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
-  todo_wine {
   ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
   ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
-  }
+  ok(dwSize == 0, "dwSize = %d\n", dwSize);
+
   dwSize = sizeof szPart;
   szPart[0]='x'; szPart[1]=0;
   res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0);
-  todo_wine {
   ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
   ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
-  }
+  ok(dwSize == 0, "dwSize = %d\n", dwSize);
 
   test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
   test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
@@ -619,9 +646,20 @@ static void test_UrlGetPart(void)
   res = pUrlGetPartA(about_url, szPart, &dwSize, URL_PART_HOSTNAME, 0);
   ok(res==E_FAIL, "returned %08x\n", res);
 
+  test_url_part(res_url, URL_PART_SCHEME, 0, "res");
+  test_url_part("http://www.winehq.org", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, "http:www.winehq.org");
+
+  dwSize = sizeof szPart;
+  szPart[0]='x'; szPart[1]=0;
+  res = pUrlGetPartA(res_url, szPart, &dwSize, URL_PART_QUERY, 0);
+  ok(res==S_FALSE, "UrlGetPartA returned %08X\n", res);
+  ok(szPart[0]==0, "UrlGetPartA gave \"%s\" instead of \"\"\n", szPart);
+  ok(dwSize == 0, "dwSize = %d\n", dwSize);
+
   dwSize = sizeof(szPart);
   res = pUrlGetPartA("file://c:\\index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0);
   ok(res==S_FALSE, "returned %08x\n", res);
+  ok(dwSize == 0, "dwSize = %d\n", dwSize);
 
   dwSize = sizeof(szPart);
   szPart[0] = 'x'; szPart[1] = '\0';
@@ -629,6 +667,11 @@ static void test_UrlGetPart(void)
   ok(res==S_FALSE, "returned %08x\n", res);
   ok(szPart[0] == '\0', "szPart[0] = %c\n", szPart[0]);
   ok(dwSize == 0, "dwSize = %d\n", dwSize);
+
+  dwSize = sizeof(szPart);
+  szPart[0] = 'x'; szPart[1] = '\0';
+  res = pUrlGetPartA("index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0);
+  ok(res==E_FAIL, "returned %08x\n", res);
 }
 
 /* ########################### */
diff --git a/dlls/shlwapi/url.c b/dlls/shlwapi/url.c
index 2fdae3d..1568714 100644
--- a/dlls/shlwapi/url.c
+++ b/dlls/shlwapi/url.c
@@ -2051,6 +2051,9 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
     LPWSTR in, out;
     DWORD ret, len, len2;
 
+    if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
+        return E_INVALIDARG;
+
     in = HeapAlloc(GetProcessHeap(), 0,
 			      (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
     out = in + INTERNET_MAX_URL_LENGTH;
@@ -2067,7 +2070,7 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
 
     len2 = WideCharToMultiByte(0, 0, out, len, 0, 0, 0, 0);
     if (len2 > *pcchOut) {
-	*pcchOut = len2;
+	*pcchOut = len2+1;
 	HeapFree(GetProcessHeap(), 0, in);
 	return E_POINTER;
     }
@@ -2093,20 +2096,25 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
     TRACE("(%s %p %p(%d) %08x %08x)\n",
 	  debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwPart, dwFlags);
 
+    if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
+        return E_INVALIDARG;
+
+    *pszOut = '\0';
+
     addr = strchrW(pszIn, ':');
     if(!addr)
-        return E_FAIL;
-
-    scheme = get_scheme_code(pszIn, addr-pszIn);
+        scheme = URL_SCHEME_UNKNOWN;
+    else
+        scheme = get_scheme_code(pszIn, addr-pszIn);
 
     ret = URL_ParseUrl(pszIn, &pl);
-    if (ret == S_OK) {
-	schaddr = pl.pScheme;
-	schsize = pl.szScheme;
 
 	switch (dwPart) {
 	case URL_PART_SCHEME:
-	    if (!pl.szScheme) return E_INVALIDARG;
+	    if (!pl.szScheme || scheme == URL_SCHEME_UNKNOWN) {
+	        *pcchOut = 0;
+	        return S_FALSE;
+	    }
 	    addr = pl.pScheme;
 	    size = pl.szScheme;
 	    break;
@@ -2121,55 +2129,76 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
             case URL_SCHEME_HTTPS:
                 break;
             default:
+                *pcchOut = 0;
                 return E_FAIL;
             }
 
             if(scheme==URL_SCHEME_FILE && (!pl.szHostName ||
                         (pl.szHostName==1 && *(pl.pHostName+1)==':'))) {
-                if(pcchOut)
-                    *pszOut = '\0';
                 *pcchOut = 0;
                 return S_FALSE;
             }
 
-	    if (!pl.szHostName) return E_INVALIDARG;
+	    if (!pl.szHostName) {
+	        *pcchOut = 0;
+	        return S_FALSE;
+	    }
 	    addr = pl.pHostName;
 	    size = pl.szHostName;
 	    break;
 
 	case URL_PART_USERNAME:
-	    if (!pl.szUserName) return E_INVALIDARG;
+	    if (!pl.szUserName) {
+	        *pcchOut = 0;
+	        return S_FALSE;
+	    }
 	    addr = pl.pUserName;
 	    size = pl.szUserName;
 	    break;
 
 	case URL_PART_PASSWORD:
-	    if (!pl.szPassword) return E_INVALIDARG;
+	    if (!pl.szPassword) {
+	        *pcchOut = 0;
+	        return S_FALSE;
+	    }
 	    addr = pl.pPassword;
 	    size = pl.szPassword;
 	    break;
 
 	case URL_PART_PORT:
-	    if (!pl.szPort) return E_INVALIDARG;
+	    if (!pl.szPort) {
+	        *pcchOut = 0;
+	        return S_FALSE;
+	    }
 	    addr = pl.pPort;
 	    size = pl.szPort;
 	    break;
 
 	case URL_PART_QUERY:
-	    if (!pl.szQuery) return E_INVALIDARG;
+	    if (!pl.szQuery) {
+	        *pcchOut = 0;
+	        return S_FALSE;
+	    }
 	    addr = pl.pQuery;
 	    size = pl.szQuery;
 	    break;
 
 	default:
+	    *pcchOut = 0;
 	    return E_INVALIDARG;
 	}
 
 	if (dwFlags == URL_PARTFLAG_KEEPSCHEME) {
+            if(!pl.pScheme || !pl.szScheme) {
+                *pcchOut = 0;
+                return E_FAIL;
+            }
+            schaddr = pl.pScheme;
+            schsize = pl.szScheme;
             if (*pcchOut < schsize + size + 2) {
                 *pcchOut = schsize + size + 2;
-		return E_POINTER;
-	    }
+                return E_POINTER;
+            }
             memcpy(pszOut, schaddr, schsize*sizeof(WCHAR));
             pszOut[schsize] = ':';
             memcpy(pszOut+schsize+1, addr, size*sizeof(WCHAR));
@@ -2183,12 +2212,6 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
 	    *pcchOut = size;
 	}
 	TRACE("len=%d %s\n", *pcchOut, debugstr_w(pszOut));
-    }else if(dwPart==URL_PART_HOSTNAME && scheme==URL_SCHEME_FILE) {
-        if(*pcchOut)
-            *pszOut = '\0';
-        *pcchOut = 0;
-        return S_FALSE;
-    }
 
     return ret;
 }
diff --git a/dlls/urlmon/sec_mgr.c b/dlls/urlmon/sec_mgr.c
index 81f2f50..f984aa4 100644
--- a/dlls/urlmon/sec_mgr.c
+++ b/dlls/urlmon/sec_mgr.c
@@ -1287,11 +1287,13 @@ HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUA
         return S_OK;
     }
 
-    hres = CoInternetParseUrl(url, PARSE_ROOTDOCUMENT, 0, domain, 0, &len, 0);
-    if(hres == S_FALSE) {
-        hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain,
-                INTERNET_MAX_URL_LENGTH, &len, 0);
-        if(hres == S_OK) {
+    hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain,
+            INTERNET_MAX_URL_LENGTH, &len, 0);
+    if(hres == S_OK){
+        const WCHAR fileW[] = {'f','i','l','e',0};
+        if(!strcmpW(domain, fileW)){
+            hres = CoInternetParseUrl(url, PARSE_ROOTDOCUMENT, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
+        }else{
             domain[len] = ':';
             hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, domain+len+1,
                     INTERNET_MAX_URL_LENGTH-len-1, &len, 0);
@@ -1305,7 +1307,8 @@ HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUA
                 return S_OK;
             }
         }
-    }
+    }else
+        return hres;
 
     len = lstrlenW(url)+1;
     *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));




More information about the wine-cvs mailing list