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

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 18 10:51:11 CDT 2016


Module: wine
Branch: master
Commit: dfa014a5723c0241a95494892d70a4ebe9126207
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dfa014a5723c0241a95494892d70a4ebe9126207

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue May 17 19:19:59 2016 +0200

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

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wininet/http.c     | 53 ++++++++++++++++++------------------
 dlls/wininet/internet.c | 72 +++++++++++++++++--------------------------------
 dlls/wininet/internet.h |  2 +-
 3 files changed, 51 insertions(+), 76 deletions(-)

diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 0f155cf..96f481e 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;
-    UrlComponents.dwHostNameLength = 1;
-
-    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 )
+    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;
+    }
 
-    if( !request->path )
-        request->path = szNul;
+    UrlComponents.dwHostNameLength = 1;
+    if(InternetCrackUrlW(proxy, 0, 0, &UrlComponents) && UrlComponents.dwHostNameLength) {
+        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;
+        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 fdad378..9751a49 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; ptr && *ptr; )
     {
-        /* It wasn't found: look for no protocol */
-        for (ptr = szProxy; !ret && ptr && *ptr; )
-        {
-            LPCWSTR end;
+        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;
+        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 8cd1a8e..91c09b8 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;




More information about the wine-cvs mailing list