Module: wine Branch: master Commit: 69ee496fbd5d88201c7b29a652121f01eb810023 URL: http://source.winehq.org/git/wine.git/?a=commit;h=69ee496fbd5d88201c7b29a652...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Feb 8 15:16:38 2011 +0100
urlmon: CoInternetGetSecurityUrl rewrite.
This includes proper URL buffers, error handling and wrong pluggable protocol calls fixes.
---
dlls/urlmon/sec_mgr.c | 202 +++++++++++++++++++++++++++++++++--------------- 1 files changed, 139 insertions(+), 63 deletions(-)
diff --git a/dlls/urlmon/sec_mgr.c b/dlls/urlmon/sec_mgr.c index 2aca1a9..4206d5d 100644 --- a/dlls/urlmon/sec_mgr.c +++ b/dlls/urlmon/sec_mgr.c @@ -1299,87 +1299,163 @@ HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneM return ZoneMgrImpl_Construct(NULL, (void**)ppZM); }
-/******************************************************************** - * CoInternetGetSecurityUrl (URLMON.@) - */ -HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved) -{ - WCHAR buf1[INTERNET_MAX_URL_LENGTH], buf2[INTERNET_MAX_URL_LENGTH]; - LPWSTR url, domain; - DWORD len; - HRESULT hres; +static HRESULT parse_security_url(const WCHAR *url, PSUACTION action, WCHAR **result) { + IInternetProtocolInfo *protocol_info; + WCHAR *tmp, *new_url = NULL, *alloc_url = NULL; + DWORD size, new_size; + HRESULT hres = S_OK, parse_hres;
- TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved); + while(1) { + TRACE("parsing %s\n", debugstr_w(url));
- url = buf1; - domain = buf2; - strcpyW(url, pwzUrl); + protocol_info = get_protocol_info(url); + if(!protocol_info) + break;
- while(1) { - hres = CoInternetParseUrl(url, PARSE_SECURITY_URL, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0); - if(hres!=S_OK || !strcmpW(url, domain)) + size = strlenW(url)+1; + new_url = CoTaskMemAlloc(size*sizeof(WCHAR)); + if(!new_url) { + hres = E_OUTOFMEMORY; break; + }
- if(url == buf1) { - url = buf2; - domain = buf1; - } else { - url = buf1; - domain = buf2; + new_size = 0; + parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, size, &new_size, 0); + if(parse_hres == S_FALSE) { + if(!new_size) { + hres = E_UNEXPECTED; + break; + } + + tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR)); + if(!tmp) { + hres = E_OUTOFMEMORY; + break; + } + new_url = tmp; + parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, + new_size, &new_size, 0); + if(parse_hres == S_FALSE) { + hres = E_FAIL; + break; + } } - }
- if(psuAction==PSU_SECURITY_URL_ONLY) { - len = lstrlenW(url)+1; - *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR)); - if(!*ppwzSecUrl) - return E_OUTOFMEMORY; + if(parse_hres != S_OK || !strcmpW(url, new_url)) + break;
- memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR)); - return S_OK; + CoTaskMemFree(alloc_url); + url = alloc_url = new_url; + new_url = NULL; }
- hres = CoInternetParseUrl(url, PARSE_SECURITY_DOMAIN, 0, domain, - INTERNET_MAX_URL_LENGTH, &len, 0); - if(SUCCEEDED(hres)) { - len++; - *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR)); - if(!*ppwzSecUrl) - return E_OUTOFMEMORY; + CoTaskMemFree(new_url);
- memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR)); - return S_OK; + if(hres != S_OK) { + WARN("failed: %08x\n", hres); + CoTaskMemFree(alloc_url); + return hres; }
- 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); - if(hres == S_OK) { - len = lstrlenW(domain)+1; - *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR)); - if(!*ppwzSecUrl) - return E_OUTOFMEMORY; - - memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR)); - return S_OK; + if(action == PSU_DEFAULT && (protocol_info = get_protocol_info(url))) { + size = strlenW(url)+1; + new_url = CoTaskMemAlloc(size * sizeof(WCHAR)); + if(new_url) { + new_size = 0; + parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, + new_url, size, &new_size, 0); + if(parse_hres == S_FALSE) { + if(new_size) { + tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR)); + if(tmp) { + new_url = tmp; + parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, new_url, + new_size, &new_size, 0); + if(parse_hres == S_FALSE) + hres = E_FAIL; + }else { + hres = E_OUTOFMEMORY; + } + }else { + hres = E_UNEXPECTED; + } + } + + if(hres == S_OK && parse_hres == S_OK) { + CoTaskMemFree(alloc_url); + url = alloc_url = new_url; + new_url = NULL; } + + CoTaskMemFree(new_url); + }else { + hres = E_OUTOFMEMORY; } - }else + IInternetProtocolInfo_Release(protocol_info); + } + + if(FAILED(hres)) { + WARN("failed %08x\n", hres); + CoTaskMemFree(alloc_url); return hres; + }
- len = lstrlenW(url)+1; - *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR)); - if(!*ppwzSecUrl) - return E_OUTOFMEMORY; + if(!alloc_url) { + size = strlenW(url)+1; + alloc_url = CoTaskMemAlloc(size * sizeof(WCHAR)); + if(!alloc_url) + return E_OUTOFMEMORY; + memcpy(alloc_url, url, size * sizeof(WCHAR)); + } + + *result = alloc_url; + return S_OK; +} + +/******************************************************************** + * CoInternetGetSecurityUrl (URLMON.@) + */ +HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved) +{ + WCHAR *secure_url; + HRESULT hres; + + TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved); + + hres = parse_security_url(pwzUrl, psuAction, &secure_url); + if(FAILED(hres)) + return hres; + + if(psuAction != PSU_SECURITY_URL_ONLY) { + PARSEDURLW parsed_url = { sizeof(parsed_url) }; + DWORD size; + + /* FIXME: Use helpers from uri.c */ + if(SUCCEEDED(ParseURLW(secure_url, &parsed_url))) { + WCHAR *new_url; + + switch(parsed_url.nScheme) { + case URL_SCHEME_FTP: + case URL_SCHEME_HTTP: + case URL_SCHEME_HTTPS: + size = strlenW(secure_url)+1; + new_url = CoTaskMemAlloc(size * sizeof(WCHAR)); + if(new_url) + hres = UrlGetPartW(secure_url, new_url, &size, URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME); + else + hres = E_OUTOFMEMORY; + CoTaskMemFree(secure_url); + if(hres != S_OK) { + WARN("UrlGetPart failed: %08x\n", hres); + CoTaskMemFree(new_url); + return FAILED(hres) ? hres : E_FAIL; + } + secure_url = new_url; + } + } + }
- memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR)); + *ppwzSecUrl = secure_url; return S_OK; }