wine-staging/patches/kernel32-GetTempPathW/0001-kernel32-Only-zero-the-buffer-up-32767-bytes-in-GetT.patch

83 lines
3.3 KiB
Diff
Raw Normal View History

From 65735c0fb4ee92078f0a368e5892455b32bccdd9 Mon Sep 17 00:00:00 2001
From: Bruno Jesus <00cpxxx@gmail.com>
Date: Sat, 14 Mar 2015 01:27:27 -0300
Subject: kernel32: Only zero the buffer up 32767 bytes in GetTempPathW
Bogus app passes the buffer size instead of WCHAR count, fortunately
it works in windows because it will only fill up to 32767 bytes with
zero. So do the same in wine.
Fixes https://bugs.winehq.org/show_bug.cgi?id=38220
---
dlls/kernel32/path.c | 5 +++--
dlls/kernel32/tests/path.c | 30 +++++++++++++++++++++++++++++-
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 7fe229f..c2833b1 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -622,8 +622,9 @@ DWORD WINAPI GetTempPathW( DWORD count, LPWSTR path )
if (count >= ret)
{
lstrcpynW(path, tmp_path, count);
- /* the remaining buffer must be zeroed */
- memset(path + ret, 0, (count - ret) * sizeof(WCHAR));
+ /* the remaining buffer must be zeroed up to 32766 bytes in XP or 32767
+ * bytes after it, we will assume the > XP behavior for now */
+ memset(path + ret, 0, (min(count, 32767) - ret) * sizeof(WCHAR));
ret--; /* return length without 0 */
}
else if (count)
diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c
index e97c50c..cdb565a 100644
--- a/dlls/kernel32/tests/path.c
+++ b/dlls/kernel32/tests/path.c
@@ -975,7 +975,7 @@ static void test_GetTempPathA(char* tmp_dir)
static void test_GetTempPathW(char* tmp_dir)
{
DWORD len, slen, len_with_null;
- WCHAR buf[MAX_PATH];
+ WCHAR buf[MAX_PATH], *long_buf;
WCHAR tmp_dirW[MAX_PATH];
static const WCHAR fooW[] = {'f','o','o',0};
@@ -1048,6 +1048,34 @@ static void test_GetTempPathW(char* tmp_dir)
ok(buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, buf[len]);
for(; len < sizeof(buf) / sizeof(buf[0]); len++)
ok(buf[len] == 'a', "expected 'a' at [%d], got 0x%x\n", len, buf[len]);
+
+ /* bogus application from bug 38220 passes the count value in sizeof(buffer)
+ * instead the correct count of WCHAR, this test catches this case. */
+ slen = 65534;
+ long_buf = HeapAlloc(GetProcessHeap(), 0, slen * sizeof(WCHAR));
+ if (!long_buf)
+ {
+ skip("Could not allocate memory for the test\n");
+ return;
+ }
+ for(len = 0; len < slen; len++)
+ long_buf[len] = 0xCC;
+ len = GetTempPathW(slen, long_buf);
+ ok(lstrcmpiW(long_buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
+ ok(len == lstrlenW(long_buf), "returned length should be equal to the length of string\n");
+ /* the remaining buffer must be zeroed up to different values in different OS versions.
+ * <= XP - 32766
+ * > XP - 32767
+ * to simplify testing we will test only until XP.
+ */
+ for(; len < 32767; len++)
+ ok(long_buf[len] == '\0', "expected NULL at [%d], got 0x%x\n", len, long_buf[len]);
+ /* we will know skip the test that is in the middle of the OS difference by
+ * incrementing len and then resume the test for the untouched part. */
+ for(len++; len < slen; len++)
+ ok(long_buf[len] == 0xcc, "expected 0xcc at [%d], got 0x%x\n", len, long_buf[len]);
+
+ HeapFree(GetProcessHeap(), 0, long_buf);
}
static void test_GetTempPath(void)
--
2.3.2