From dd46af25902e30891bb02437e2f39c05b36a495a Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sun, 17 Apr 2016 15:27:17 +0200 Subject: [PATCH] Added patch to fix handling of wildcard paths in GetShortPathName and GetLongPathName. --- ...dd-some-tests-for-GetLongPathName-Ge.patch | 69 +++++++++++++++++++ ...tPathName-should-fail-when-called-wi.patch | 63 +++++++++++++++++ ...PathName-should-fail-when-called-wit.patch | 62 +++++++++++++++++ patches/kernel32-GetShortPathName/definition | 1 + patches/patchinstall.sh | 23 +++++++ 5 files changed, 218 insertions(+) create mode 100644 patches/kernel32-GetShortPathName/0001-kernel32-tests-Add-some-tests-for-GetLongPathName-Ge.patch create mode 100644 patches/kernel32-GetShortPathName/0002-kernel32-GetShortPathName-should-fail-when-called-wi.patch create mode 100644 patches/kernel32-GetShortPathName/0003-kernel32-GetLongPathName-should-fail-when-called-wit.patch create mode 100644 patches/kernel32-GetShortPathName/definition diff --git a/patches/kernel32-GetShortPathName/0001-kernel32-tests-Add-some-tests-for-GetLongPathName-Ge.patch b/patches/kernel32-GetShortPathName/0001-kernel32-tests-Add-some-tests-for-GetLongPathName-Ge.patch new file mode 100644 index 00000000..9a7f0b7c --- /dev/null +++ b/patches/kernel32-GetShortPathName/0001-kernel32-tests-Add-some-tests-for-GetLongPathName-Ge.patch @@ -0,0 +1,69 @@ +From 8f0f5577096155171dceb98ee28c570533a9a89c Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 17 Apr 2016 19:58:15 +0800 +Subject: kernel32/tests: Add some tests for GetLongPathName/GetShortPathName + called with a wildcard. + +--- + dlls/kernel32/tests/path.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c +index 079820f..0dc8802 100644 +--- a/dlls/kernel32/tests/path.c ++++ b/dlls/kernel32/tests/path.c +@@ -1170,7 +1170,7 @@ static void test_GetTempPath(void) + static void test_GetLongPathNameA(void) + { + DWORD length, explength, hostsize; +- char tempfile[MAX_PATH]; ++ char tempfile[MAX_PATH], *name; + char longpath[MAX_PATH]; + char unc_prefix[MAX_PATH]; + char unc_short[MAX_PATH], unc_long[MAX_PATH]; +@@ -1181,7 +1181,17 @@ static void test_GetLongPathNameA(void) + return; + + GetTempPathA(MAX_PATH, tempfile); +- lstrcatA(tempfile, "longfilename.longext"); ++ name = tempfile + strlen(tempfile); ++ ++ strcpy(name, "*"); ++ SetLastError(0xdeadbeef); ++ length = pGetLongPathNameA(tempfile, temppath, MAX_PATH); ++todo_wine ++ ok(!length, "GetLongPathNameA should fail\n"); ++todo_wine ++ ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", GetLastError()); ++ ++ strcpy(name, "longfilename.longext"); + + file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + CloseHandle(file); +@@ -1385,6 +1395,7 @@ static void test_GetShortPathNameW(void) + static const WCHAR name[] = { 't', 'e', 's', 't', 0 }; + static const WCHAR backSlash[] = { '\\', 0 }; + static const WCHAR a_bcdeW[] = {'a','.','b','c','d','e',0}; ++ static const WCHAR wildW[] = { '*',0 }; + WCHAR path[MAX_PATH], tmppath[MAX_PATH], *ptr; + WCHAR short_path[MAX_PATH]; + DWORD length; +@@ -1447,6 +1458,15 @@ static void test_GetShortPathNameW(void) + length = GetShortPathNameW( path, short_path, sizeof(short_path)/sizeof(*short_path) ); + ok( length, "GetShortPathNameW failed: %u.\n", GetLastError() ); + ++ lstrcpyW(ptr, wildW); ++ SetLastError(0xdeadbeef); ++ length = GetShortPathNameW( path, short_path, sizeof(short_path)/sizeof(*short_path) ); ++todo_wine ++ ok(!length, "GetShortPathNameW should fail\n"); ++todo_wine ++ ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", GetLastError()); ++ ++ lstrcpyW(ptr, a_bcdeW); + ret = DeleteFileW( path ); + ok( ret, "Cannot delete file.\n" ); + *ptr = 0; +-- +2.7.1 + diff --git a/patches/kernel32-GetShortPathName/0002-kernel32-GetShortPathName-should-fail-when-called-wi.patch b/patches/kernel32-GetShortPathName/0002-kernel32-GetShortPathName-should-fail-when-called-wi.patch new file mode 100644 index 00000000..cb6ec0a1 --- /dev/null +++ b/patches/kernel32-GetShortPathName/0002-kernel32-GetShortPathName-should-fail-when-called-wi.patch @@ -0,0 +1,63 @@ +From d43c0229efb42913a0902ee42817e3a928598587 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 17 Apr 2016 20:06:46 +0800 +Subject: kernel32: GetShortPathName should fail when called with a wildcard. + +This patch fixes heap corruption reported in the bug 39355. +--- + dlls/kernel32/path.c | 10 +++++++++- + dlls/kernel32/tests/path.c | 2 -- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c +index a906acc..ecebab2 100644 +--- a/dlls/kernel32/path.c ++++ b/dlls/kernel32/path.c +@@ -43,6 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); + + #define MAX_PATHNAME_LEN 1024 + ++static const WCHAR wildcardsW[] = {'*','?',0}; + + /* check if a file name is for an executable file (.exe or .com) */ + static inline BOOL is_executable( const WCHAR *name ) +@@ -455,7 +456,7 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl + WIN32_FIND_DATAW wfd; + HANDLE goit; + +- TRACE("%s\n", debugstr_w(longpath)); ++ TRACE("%s,%p,%u\n", debugstr_w(longpath), shortpath, shortlen); + + if (!longpath) + { +@@ -484,6 +485,13 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl + sp = lp = 4; + } + ++ if (strpbrkW(longpath + lp, wildcardsW)) ++ { ++ HeapFree(GetProcessHeap(), 0, tmpshortpath); ++ SetLastError(ERROR_INVALID_NAME); ++ return 0; ++ } ++ + /* check for drive letter */ + if (longpath[lp] != '/' && longpath[lp + 1] == ':' ) + { +diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c +index 0dc8802..3934046 100644 +--- a/dlls/kernel32/tests/path.c ++++ b/dlls/kernel32/tests/path.c +@@ -1461,9 +1461,7 @@ static void test_GetShortPathNameW(void) + lstrcpyW(ptr, wildW); + SetLastError(0xdeadbeef); + length = GetShortPathNameW( path, short_path, sizeof(short_path)/sizeof(*short_path) ); +-todo_wine + ok(!length, "GetShortPathNameW should fail\n"); +-todo_wine + ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", GetLastError()); + + lstrcpyW(ptr, a_bcdeW); +-- +2.7.1 + diff --git a/patches/kernel32-GetShortPathName/0003-kernel32-GetLongPathName-should-fail-when-called-wit.patch b/patches/kernel32-GetShortPathName/0003-kernel32-GetLongPathName-should-fail-when-called-wit.patch new file mode 100644 index 00000000..8565e1d1 --- /dev/null +++ b/patches/kernel32-GetShortPathName/0003-kernel32-GetLongPathName-should-fail-when-called-wit.patch @@ -0,0 +1,62 @@ +From b1ab2f65a23534e70e084f777f2ed75c615e1696 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 17 Apr 2016 20:15:35 +0800 +Subject: kernel32: GetLongPathName should fail when called with a wildcard. + +--- + dlls/kernel32/path.c | 10 ++++++++-- + dlls/kernel32/tests/path.c | 2 -- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c +index ecebab2..17b9851 100644 +--- a/dlls/kernel32/path.c ++++ b/dlls/kernel32/path.c +@@ -295,6 +295,8 @@ DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen + HANDLE goit; + BOOL is_legal_8dot3; + ++ TRACE("%s,%p,%u\n", debugstr_w(shortpath), longpath, longlen); ++ + if (!shortpath) + { + SetLastError(ERROR_INVALID_PARAMETER); +@@ -306,8 +308,6 @@ DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen + return 0; + } + +- TRACE("%s,%p,%d\n", debugstr_w(shortpath), longpath, longlen); +- + if (shortpath[0] == '\\' && shortpath[1] == '\\') + { + FIXME("UNC pathname %s\n", debugstr_w(shortpath)); +@@ -331,6 +331,12 @@ DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen + lp = sp = 2; + } + ++ if (strpbrkW(shortpath + sp, wildcardsW)) ++ { ++ SetLastError(ERROR_INVALID_NAME); ++ return 0; ++ } ++ + while (shortpath[sp]) + { + /* check for path delimiters and reproduce them */ +diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c +index 3934046..4d23fbc 100644 +--- a/dlls/kernel32/tests/path.c ++++ b/dlls/kernel32/tests/path.c +@@ -1186,9 +1186,7 @@ static void test_GetLongPathNameA(void) + strcpy(name, "*"); + SetLastError(0xdeadbeef); + length = pGetLongPathNameA(tempfile, temppath, MAX_PATH); +-todo_wine + ok(!length, "GetLongPathNameA should fail\n"); +-todo_wine + ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", GetLastError()); + + strcpy(name, "longfilename.longext"); +-- +2.7.1 + diff --git a/patches/kernel32-GetShortPathName/definition b/patches/kernel32-GetShortPathName/definition new file mode 100644 index 00000000..8138cc2d --- /dev/null +++ b/patches/kernel32-GetShortPathName/definition @@ -0,0 +1 @@ +Fixes: [39355] Fix handling of wildcard paths in GetShortPathName and GetLongPathName diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 72c8141b..de09fc0e 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -166,6 +166,7 @@ patch_enable_all () enable_kernel32_FindFirstFile="$1" enable_kernel32_FreeUserPhysicalPages="$1" enable_kernel32_GetCurrentPackageFamilyName="$1" + enable_kernel32_GetShortPathName="$1" enable_kernel32_LocaleNameToLCID="$1" enable_kernel32_Named_Pipe="$1" enable_kernel32_NeedCurrentDirectoryForExePath="$1" @@ -676,6 +677,9 @@ patch_enable () kernel32-GetCurrentPackageFamilyName) enable_kernel32_GetCurrentPackageFamilyName="$2" ;; + kernel32-GetShortPathName) + enable_kernel32_GetShortPathName="$2" + ;; kernel32-LocaleNameToLCID) enable_kernel32_LocaleNameToLCID="$2" ;; @@ -4016,6 +4020,25 @@ if test "$enable_kernel32_FindFirstFile" -eq 1; then ) >> "$patchlist" fi +# Patchset kernel32-GetShortPathName +# | +# | This patchset fixes the following Wine bugs: +# | * [#39355] Fix handling of wildcard paths in GetShortPathName and GetLongPathName +# | +# | Modified files: +# | * dlls/kernel32/path.c, dlls/kernel32/tests/path.c +# | +if test "$enable_kernel32_GetShortPathName" -eq 1; then + patch_apply kernel32-GetShortPathName/0001-kernel32-tests-Add-some-tests-for-GetLongPathName-Ge.patch + patch_apply kernel32-GetShortPathName/0002-kernel32-GetShortPathName-should-fail-when-called-wi.patch + patch_apply kernel32-GetShortPathName/0003-kernel32-GetLongPathName-should-fail-when-called-wit.patch + ( + echo '+ { "Dmitry Timoshkov", "kernel32/tests: Add some tests for GetLongPathName/GetShortPathName called with a wildcard.", 1 },'; + echo '+ { "Dmitry Timoshkov", "kernel32: GetShortPathName should fail when called with a wildcard.", 1 },'; + echo '+ { "Dmitry Timoshkov", "kernel32: GetLongPathName should fail when called with a wildcard.", 1 },'; + ) >> "$patchlist" +fi + # Patchset kernel32-LocaleNameToLCID # | # | This patchset fixes the following Wine bugs: