From e60b2ec90733a76e803697e551f6bdfe97ff4dc8 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Fri, 12 Mar 2010 17:22:43 -0600 Subject: [PATCH] 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 31df64e48ab..944d679a299 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@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 2fdae3de523..156871425da 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 81f2f507d0d..f984aa4e907 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));