Piotr Caban : wininet: Improve handling of long URLs in CreateUrlCacheEntry function.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jun 19 07:19:13 CDT 2015


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri Jun 19 08:58:55 2015 +0200

wininet: Improve handling of long URLs in CreateUrlCacheEntry function.

---

 dlls/wininet/tests/urlcache.c | 26 ++++++++++++++++++++++++++
 dlls/wininet/urlcache.c       | 34 +++++++++++++++++++++++++---------
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/dlls/wininet/tests/urlcache.c b/dlls/wininet/tests/urlcache.c
index f4d1e35..37ee412 100644
--- a/dlls/wininet/tests/urlcache.c
+++ b/dlls/wininet/tests/urlcache.c
@@ -363,6 +363,7 @@ static void create_and_write_file(LPCSTR filename, void *data, DWORD len)
 
 static void test_urlcacheA(void)
 {
+    static char long_url[300] = "http://www.winehq.org/";
     static char ok_header[] = "HTTP/1.0 200 OK\r\n\r\n";
     BOOL ret;
     HANDLE hFile;
@@ -372,6 +373,7 @@ static void test_urlcacheA(void)
     DWORD cbCacheEntryInfo;
     static const FILETIME filetime_zero;
     FILETIME now;
+    int len;
 
     ret = CreateUrlCacheEntryA(test_url, 0, "html", filenameA, 0);
     ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
@@ -807,6 +809,30 @@ static void test_urlcacheA(void)
         ret = pDeleteUrlCacheEntryA(test_hash_collisions2);
         ok(ret, "DeleteUrlCacheEntry failed: %d\n", GetLastError());
     }
+
+    len = strlen(long_url);
+    memset(long_url+len, 'a', sizeof(long_url)-len);
+    long_url[sizeof(long_url)-1] = 0;
+    ret = CreateUrlCacheEntryA(long_url, 0, NULL, filenameA, 0);
+    ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
+    check_file_exists(filenameA);
+    DeleteFileA(filenameA);
+
+    ret = CreateUrlCacheEntryA(long_url, 0, "extension", filenameA, 0);
+    ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
+    check_file_exists(filenameA);
+    DeleteFileA(filenameA);
+
+    long_url[250] = 0;
+    ret = CreateUrlCacheEntryA(long_url, 0, NULL, filenameA, 0);
+    ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
+    check_file_exists(filenameA);
+    DeleteFileA(filenameA);
+
+    ret = CreateUrlCacheEntryA(long_url, 0, "extension", filenameA, 0);
+    ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
+    check_file_exists(filenameA);
+    DeleteFileA(filenameA);
 }
 
 static void test_urlcacheW(void)
diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c
index 0e5fe3c..3229f21 100644
--- a/dlls/wininet/urlcache.c
+++ b/dlls/wininet/urlcache.c
@@ -979,7 +979,8 @@ static BOOL urlcache_create_file_pathW(
     LPCSTR szLocalFileName,
     BYTE Directory,
     LPWSTR wszPath,
-    LPLONG lpBufferSize)
+    LPLONG lpBufferSize,
+    BOOL trunc_name)
 {
     LONG nRequired;
     int path_len = strlenW(pContainer->path);
@@ -993,6 +994,8 @@ static BOOL urlcache_create_file_pathW(
     nRequired = (path_len + file_name_len) * sizeof(WCHAR);
     if(Directory != CACHE_CONTAINER_NO_SUBDIR)
         nRequired += (DIR_LENGTH + 1) * sizeof(WCHAR);
+    if (trunc_name && nRequired >= *lpBufferSize)
+        nRequired = *lpBufferSize;
     if (nRequired <= *lpBufferSize)
     {
         int dir_len;
@@ -1008,7 +1011,9 @@ static BOOL urlcache_create_file_pathW(
         {
             dir_len = 0;
         }
-        MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len, file_name_len);
+        MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len,
+                *lpBufferSize/sizeof(WCHAR)-dir_len-path_len);
+        wszPath[*lpBufferSize/sizeof(WCHAR)-1] = 0;
         *lpBufferSize = nRequired;
         return TRUE;
     }
@@ -1097,7 +1102,7 @@ static DWORD urlcache_delete_file(const cache_container *container,
 
     if(!urlcache_create_file_pathW(container, header,
                 (LPCSTR)url_entry+url_entry->local_name_off,
-                url_entry->cache_dir, path, &path_size))
+                url_entry->cache_dir, path, &path_size, FALSE))
         goto succ;
 
     if(!GetFileAttributesExW(path, GetFileExInfoStandard, &attr))
@@ -1320,8 +1325,10 @@ static DWORD urlcache_copy_entry(cache_container *container, const urlcache_head
         LPSTR file_name;
         file_name = (LPSTR)entry_info+size;
         file_name_size = *info_size-size;
-        if((unicode && urlcache_create_file_pathW(container, header, (LPCSTR)url_entry+url_entry->local_name_off, url_entry->cache_dir, (LPWSTR)file_name, &file_name_size)) ||
-            (!unicode && urlcache_create_file_pathA(container, header, (LPCSTR)url_entry+url_entry->local_name_off, url_entry->cache_dir, file_name, &file_name_size))) {
+        if((unicode && urlcache_create_file_pathW(container, header, (LPCSTR)url_entry+url_entry->local_name_off,
+                        url_entry->cache_dir, (LPWSTR)file_name, &file_name_size, FALSE)) ||
+            (!unicode && urlcache_create_file_pathA(container, header, (LPCSTR)url_entry+url_entry->local_name_off,
+                        url_entry->cache_dir, file_name, &file_name_size))) {
             entry_info->lpszLocalFileName = file_name;
         }
         size += file_name_size;
@@ -2613,7 +2620,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
     char file_name[MAX_PATH];
     WCHAR extW[MAX_PATH];
     BYTE cache_dir;
-    LONG full_path_len;
+    LONG full_path_len, ext_len = 0;
     BOOL generate_name = FALSE;
     DWORD error;
     HANDLE file;
@@ -2630,7 +2637,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
     if(!InternetCrackUrlA(url, 0, 0, &uc))
         uc.dwUrlPathLength = 0;
 
-    if(!uc.dwUrlPathLength || uc.dwUrlPathLength >= sizeof(file_name)) {
+    if(!uc.dwUrlPathLength) {
         file_name[0] = 0;
     }else {
         char *p, *e;
@@ -2644,6 +2651,8 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
                 p--;
         }
 
+        if(e-p >= MAX_PATH)
+            e = p+MAX_PATH-1;
         memcpy(file_name, p, e-p);
         file_name[e-p] = 0;
 
@@ -2683,7 +2692,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
         cache_dir = CACHE_CONTAINER_NO_SUBDIR;
 
     full_path_len = MAX_PATH * sizeof(WCHAR);
-    if(!urlcache_create_file_pathW(container, header, file_name, cache_dir, full_path, &full_path_len)) {
+    if(!urlcache_create_file_pathW(container, header, file_name, cache_dir, full_path, &full_path_len, TRUE)) {
         WARN("Failed to get full path for filename %s, needed %u bytes.\n",
                 debugstr_a(file_name), full_path_len);
         cache_container_unlock_index(container, header);
@@ -2697,7 +2706,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
         WCHAR *p;
 
         extW[0] = '.';
-        MultiByteToWideChar(CP_ACP, 0, ext, -1, extW+1, MAX_PATH-1);
+        ext_len = MultiByteToWideChar(CP_ACP, 0, ext, -1, extW+1, MAX_PATH-1);
 
         for(p=extW; *p; p++) {
             switch(*p) {
@@ -2715,6 +2724,10 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
         extW[0] = '\0';
     }
 
+    if(!generate_name && full_path_len+5+ext_len>=MAX_PATH) { /* strlen("[255]") = 5 */
+        full_path_len = MAX_PATH-5-ext_len-1;
+    }
+
     for(i=0; i<255 && !generate_name; i++) {
         static const WCHAR format[] = {'[','%','u',']','%','s',0};
 
@@ -2728,6 +2741,9 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
         }
     }
 
+    if(full_path_len+8+ext_len >= MAX_PATH)
+        full_path_len = MAX_PATH-8-ext_len-1;
+
     /* Try to generate random name */
     GetSystemTimeAsFileTime(&ft);
     strcpyW(full_path+full_path_len+8, extW);




More information about the wine-cvs mailing list