Commit e60b2ec9 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

shlwapi: Improve error handling in UrlGetPart.

parent ee891d3b
...@@ -542,6 +542,14 @@ static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const ...@@ -542,6 +542,14 @@ static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const
HRESULT res; HRESULT res;
DWORD dwSize; 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; dwSize = INTERNET_MAX_URL_LENGTH;
res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags); res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags);
ok(res == S_OK, ok(res == S_OK,
...@@ -575,6 +583,7 @@ static void test_UrlGetPart(void) ...@@ -575,6 +583,7 @@ static void test_UrlGetPart(void)
{ {
const char* file_url = "file://h o s t/c:/windows/file"; 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* 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"; const char* about_url = "about:blank";
CHAR szPart[INTERNET_MAX_URL_LENGTH]; CHAR szPart[INTERNET_MAX_URL_LENGTH];
...@@ -586,20 +595,38 @@ static void test_UrlGetPart(void) ...@@ -586,20 +595,38 @@ static void test_UrlGetPart(void)
return; 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; dwSize = sizeof szPart;
szPart[0]='x'; szPart[1]=0; szPart[0]='x'; szPart[1]=0;
res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0); res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
todo_wine {
ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res); ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart); ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
} ok(dwSize == 0, "dwSize = %d\n", dwSize);
dwSize = sizeof szPart; dwSize = sizeof szPart;
szPart[0]='x'; szPart[1]=0; szPart[0]='x'; szPart[1]=0;
res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0); res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0);
todo_wine {
ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res); ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res);
ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart); 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_HOSTNAME, 0, "localhost");
test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21"); test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
...@@ -619,9 +646,20 @@ static void test_UrlGetPart(void) ...@@ -619,9 +646,20 @@ static void test_UrlGetPart(void)
res = pUrlGetPartA(about_url, szPart, &dwSize, URL_PART_HOSTNAME, 0); res = pUrlGetPartA(about_url, szPart, &dwSize, URL_PART_HOSTNAME, 0);
ok(res==E_FAIL, "returned %08x\n", res); 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); dwSize = sizeof(szPart);
res = pUrlGetPartA("file://c:\\index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0); res = pUrlGetPartA("file://c:\\index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0);
ok(res==S_FALSE, "returned %08x\n", res); ok(res==S_FALSE, "returned %08x\n", res);
ok(dwSize == 0, "dwSize = %d\n", dwSize);
dwSize = sizeof(szPart); dwSize = sizeof(szPart);
szPart[0] = 'x'; szPart[1] = '\0'; szPart[0] = 'x'; szPart[1] = '\0';
...@@ -629,6 +667,11 @@ static void test_UrlGetPart(void) ...@@ -629,6 +667,11 @@ static void test_UrlGetPart(void)
ok(res==S_FALSE, "returned %08x\n", res); ok(res==S_FALSE, "returned %08x\n", res);
ok(szPart[0] == '\0', "szPart[0] = %c\n", szPart[0]); ok(szPart[0] == '\0', "szPart[0] = %c\n", szPart[0]);
ok(dwSize == 0, "dwSize = %d\n", dwSize); 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);
} }
/* ########################### */ /* ########################### */
......
...@@ -2051,6 +2051,9 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, ...@@ -2051,6 +2051,9 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
LPWSTR in, out; LPWSTR in, out;
DWORD ret, len, len2; DWORD ret, len, len2;
if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
return E_INVALIDARG;
in = HeapAlloc(GetProcessHeap(), 0, in = HeapAlloc(GetProcessHeap(), 0,
(2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR)); (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
out = in + INTERNET_MAX_URL_LENGTH; out = in + INTERNET_MAX_URL_LENGTH;
...@@ -2067,7 +2070,7 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, ...@@ -2067,7 +2070,7 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
len2 = WideCharToMultiByte(0, 0, out, len, 0, 0, 0, 0); len2 = WideCharToMultiByte(0, 0, out, len, 0, 0, 0, 0);
if (len2 > *pcchOut) { if (len2 > *pcchOut) {
*pcchOut = len2; *pcchOut = len2+1;
HeapFree(GetProcessHeap(), 0, in); HeapFree(GetProcessHeap(), 0, in);
return E_POINTER; return E_POINTER;
} }
...@@ -2093,20 +2096,25 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, ...@@ -2093,20 +2096,25 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
TRACE("(%s %p %p(%d) %08x %08x)\n", TRACE("(%s %p %p(%d) %08x %08x)\n",
debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwPart, dwFlags); debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwPart, dwFlags);
if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
return E_INVALIDARG;
*pszOut = '\0';
addr = strchrW(pszIn, ':'); addr = strchrW(pszIn, ':');
if(!addr) if(!addr)
return E_FAIL; scheme = URL_SCHEME_UNKNOWN;
else
scheme = get_scheme_code(pszIn, addr-pszIn); scheme = get_scheme_code(pszIn, addr-pszIn);
ret = URL_ParseUrl(pszIn, &pl); ret = URL_ParseUrl(pszIn, &pl);
if (ret == S_OK) {
schaddr = pl.pScheme;
schsize = pl.szScheme;
switch (dwPart) { switch (dwPart) {
case URL_PART_SCHEME: 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; addr = pl.pScheme;
size = pl.szScheme; size = pl.szScheme;
break; break;
...@@ -2121,55 +2129,76 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, ...@@ -2121,55 +2129,76 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
case URL_SCHEME_HTTPS: case URL_SCHEME_HTTPS:
break; break;
default: default:
*pcchOut = 0;
return E_FAIL; return E_FAIL;
} }
if(scheme==URL_SCHEME_FILE && (!pl.szHostName || if(scheme==URL_SCHEME_FILE && (!pl.szHostName ||
(pl.szHostName==1 && *(pl.pHostName+1)==':'))) { (pl.szHostName==1 && *(pl.pHostName+1)==':'))) {
if(pcchOut)
*pszOut = '\0';
*pcchOut = 0; *pcchOut = 0;
return S_FALSE; return S_FALSE;
} }
if (!pl.szHostName) return E_INVALIDARG; if (!pl.szHostName) {
*pcchOut = 0;
return S_FALSE;
}
addr = pl.pHostName; addr = pl.pHostName;
size = pl.szHostName; size = pl.szHostName;
break; break;
case URL_PART_USERNAME: case URL_PART_USERNAME:
if (!pl.szUserName) return E_INVALIDARG; if (!pl.szUserName) {
*pcchOut = 0;
return S_FALSE;
}
addr = pl.pUserName; addr = pl.pUserName;
size = pl.szUserName; size = pl.szUserName;
break; break;
case URL_PART_PASSWORD: case URL_PART_PASSWORD:
if (!pl.szPassword) return E_INVALIDARG; if (!pl.szPassword) {
*pcchOut = 0;
return S_FALSE;
}
addr = pl.pPassword; addr = pl.pPassword;
size = pl.szPassword; size = pl.szPassword;
break; break;
case URL_PART_PORT: case URL_PART_PORT:
if (!pl.szPort) return E_INVALIDARG; if (!pl.szPort) {
*pcchOut = 0;
return S_FALSE;
}
addr = pl.pPort; addr = pl.pPort;
size = pl.szPort; size = pl.szPort;
break; break;
case URL_PART_QUERY: case URL_PART_QUERY:
if (!pl.szQuery) return E_INVALIDARG; if (!pl.szQuery) {
*pcchOut = 0;
return S_FALSE;
}
addr = pl.pQuery; addr = pl.pQuery;
size = pl.szQuery; size = pl.szQuery;
break; break;
default: default:
*pcchOut = 0;
return E_INVALIDARG; return E_INVALIDARG;
} }
if (dwFlags == URL_PARTFLAG_KEEPSCHEME) { 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) { if (*pcchOut < schsize + size + 2) {
*pcchOut = schsize + size + 2; *pcchOut = schsize + size + 2;
return E_POINTER; return E_POINTER;
} }
memcpy(pszOut, schaddr, schsize*sizeof(WCHAR)); memcpy(pszOut, schaddr, schsize*sizeof(WCHAR));
pszOut[schsize] = ':'; pszOut[schsize] = ':';
memcpy(pszOut+schsize+1, addr, size*sizeof(WCHAR)); memcpy(pszOut+schsize+1, addr, size*sizeof(WCHAR));
...@@ -2183,12 +2212,6 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, ...@@ -2183,12 +2212,6 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
*pcchOut = size; *pcchOut = size;
} }
TRACE("len=%d %s\n", *pcchOut, debugstr_w(pszOut)); 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; return ret;
} }
......
...@@ -1287,11 +1287,13 @@ HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUA ...@@ -1287,11 +1287,13 @@ HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUA
return S_OK; return S_OK;
} }
hres = CoInternetParseUrl(url, PARSE_ROOTDOCUMENT, 0, domain, 0, &len, 0); hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain,
if(hres == S_FALSE) { INTERNET_MAX_URL_LENGTH, &len, 0);
hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain, if(hres == S_OK){
INTERNET_MAX_URL_LENGTH, &len, 0); const WCHAR fileW[] = {'f','i','l','e',0};
if(hres == S_OK) { if(!strcmpW(domain, fileW)){
hres = CoInternetParseUrl(url, PARSE_ROOTDOCUMENT, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
}else{
domain[len] = ':'; domain[len] = ':';
hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, domain+len+1, hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, domain+len+1,
INTERNET_MAX_URL_LENGTH-len-1, &len, 0); INTERNET_MAX_URL_LENGTH-len-1, &len, 0);
...@@ -1305,7 +1307,8 @@ HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUA ...@@ -1305,7 +1307,8 @@ HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUA
return S_OK; return S_OK;
} }
} }
} }else
return hres;
len = lstrlenW(url)+1; len = lstrlenW(url)+1;
*ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR)); *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment