From dfa014a5723c0241a95494892d70a4ebe9126207 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 17 May 2016 19:19:59 +0200 Subject: [PATCH] wininet: Don't assume maximum URL length in HTTP_DealWithProxy. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/wininet/http.c | 55 +++++++++++++++--------------- dlls/wininet/internet.c | 74 ++++++++++++++--------------------------- dlls/wininet/internet.h | 2 +- 3 files changed, 53 insertions(+), 78 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 0f155cf48c..96f481e3b6 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -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; diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index fdad3786b2..9751a49dfc 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -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; } /*********************************************************************** diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 8cd1a8e522..91c09b8b72 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -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;