wininet: Don't assume maximum URL length in HTTP_DealWithProxy.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2016-05-17 19:19:59 +02:00 committed by Alexandre Julliard
parent 3413d01764
commit dfa014a572
3 changed files with 53 additions and 78 deletions

View File

@ -1788,40 +1788,39 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req
{
static const WCHAR protoHttp[] = { 'h','t','t','p',0 };
static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 };
static const WCHAR szFormat[] = { 'h','t','t','p',':','/','/','%','s',0 };
WCHAR protoProxy[INTERNET_MAX_URL_LENGTH];
DWORD protoProxyLen = INTERNET_MAX_URL_LENGTH;
WCHAR proxy[INTERNET_MAX_URL_LENGTH];
static WCHAR szNul[] = { 0 };
URL_COMPONENTSW UrlComponents;
server_t *new_server;
URL_COMPONENTSW UrlComponents = { sizeof(UrlComponents) };
server_t *new_server = NULL;
WCHAR *proxy;
BOOL is_https;
memset( &UrlComponents, 0, sizeof UrlComponents );
UrlComponents.dwStructSize = sizeof UrlComponents;
proxy = INTERNET_FindProxyForProtocol(hIC->proxy, protoHttp);
if(!proxy)
return FALSE;
if(CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
proxy, strlenW(szHttp), szHttp, strlenW(szHttp))) {
WCHAR *proxy_url = heap_alloc(strlenW(proxy)*sizeof(WCHAR) + sizeof(szHttp));
if(!proxy_url)
return FALSE;
strcpyW(proxy_url, szHttp);
strcatW(proxy_url, proxy);
heap_free(proxy);
proxy = proxy_url;
}
UrlComponents.dwHostNameLength = 1;
if(InternetCrackUrlW(proxy, 0, 0, &UrlComponents) && UrlComponents.dwHostNameLength) {
if( !request->path )
request->path = szNul;
if (!INTERNET_FindProxyForProtocol(hIC->proxy, protoHttp, protoProxy, &protoProxyLen))
return FALSE;
if( CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
protoProxy,strlenW(szHttp),szHttp,strlenW(szHttp)) )
sprintfW(proxy, szFormat, protoProxy);
else
strcpyW(proxy, protoProxy);
if( !InternetCrackUrlW(proxy, 0, 0, &UrlComponents) )
return FALSE;
if( UrlComponents.dwHostNameLength == 0 )
return FALSE;
is_https = (UrlComponents.nScheme == INTERNET_SCHEME_HTTPS);
if (is_https && UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
UrlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
if( !request->path )
request->path = szNul;
is_https = (UrlComponents.nScheme == INTERNET_SCHEME_HTTPS);
if (is_https && UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
UrlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
new_server = get_server(substr(UrlComponents.lpszHostName, UrlComponents.dwHostNameLength),
UrlComponents.nPort, is_https, TRUE);
new_server = get_server(substr(UrlComponents.lpszHostName, UrlComponents.dwHostNameLength),
UrlComponents.nPort, is_https, TRUE);
}
heap_free(proxy);
if(!new_server)
return FALSE;

View File

@ -390,15 +390,15 @@ static LONG INTERNET_SaveProxySettings( proxyinfo_t *lpwpi )
* *foundProxyLen is set to the required size in WCHARs, including the
* NULL terminator, and the last error is set to ERROR_INSUFFICIENT_BUFFER.
*/
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen)
WCHAR *INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto)
{
LPCWSTR ptr;
BOOL ret = FALSE;
WCHAR *ret = NULL;
const WCHAR *ptr;
TRACE("(%s, %s)\n", debugstr_w(szProxy), debugstr_w(proto));
/* First, look for the specified protocol (proto=scheme://host:port) */
for (ptr = szProxy; !ret && ptr && *ptr; )
for (ptr = szProxy; ptr && *ptr; )
{
LPCWSTR end, equal;
@ -408,60 +408,36 @@ BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundP
equal - ptr == strlenW(proto) &&
!strncmpiW(proto, ptr, strlenW(proto)))
{
if (end - equal > *foundProxyLen)
{
WARN("buffer too short for %s\n",
debugstr_wn(equal + 1, end - equal - 1));
*foundProxyLen = end - equal;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
else
{
memcpy(foundProxy, equal + 1, (end - equal) * sizeof(WCHAR));
foundProxy[end - equal] = 0;
ret = TRUE;
}
ret = heap_strndupW(equal + 1, end - equal - 1);
TRACE("found proxy for %s: %s\n", debugstr_w(proto), debugstr_w(ret));
return ret;
}
if (*end == ' ')
ptr = end + 1;
else
ptr = end;
}
if (!ret)
{
/* It wasn't found: look for no protocol */
for (ptr = szProxy; !ret && ptr && *ptr; )
{
LPCWSTR end;
if (!(end = strchrW(ptr, ' ')))
end = ptr + strlenW(ptr);
if (!strchrW(ptr, '='))
{
if (end - ptr + 1 > *foundProxyLen)
{
WARN("buffer too short for %s\n",
debugstr_wn(ptr, end - ptr));
*foundProxyLen = end - ptr + 1;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
else
{
memcpy(foundProxy, ptr, (end - ptr) * sizeof(WCHAR));
foundProxy[end - ptr] = 0;
ret = TRUE;
}
}
if (*end == ' ')
ptr = end + 1;
else
ptr = end;
/* It wasn't found: look for no protocol */
for (ptr = szProxy; ptr && *ptr; )
{
LPCWSTR end;
if (!(end = strchrW(ptr, ' ')))
end = ptr + strlenW(ptr);
if (!strchrW(ptr, '='))
{
ret = heap_strndupW(ptr, end - ptr);
TRACE("found proxy for %s: %s\n", debugstr_w(proto), debugstr_w(ret));
return ret;
}
if (*end == ' ')
ptr = end + 1;
else
ptr = end;
}
if (ret)
TRACE("found proxy for %s: %s\n", debugstr_w(proto),
debugstr_w(foundProxy));
return ret;
return NULL;
}
/***********************************************************************

View File

@ -450,7 +450,7 @@ VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen) DECLSPEC_HIDDEN;
WCHAR *INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto) DECLSPEC_HIDDEN;
DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN;
void free_netconn(netconn_t*) DECLSPEC_HIDDEN;