diff --git a/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch b/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch new file mode 100644 index 00000000..5ff4df95 --- /dev/null +++ b/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch @@ -0,0 +1,49 @@ +From 07791ffe43d1fda2618994f98986ab5e9cbf3c97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 18:31:25 +0100 +Subject: kernel32: Strip invalid characters from mask in FindFirstFileExW. + +--- + dlls/kernel32/file.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c +index b6dba6a..3297f4b 100644 +--- a/dlls/kernel32/file.c ++++ b/dlls/kernel32/file.c +@@ -2009,12 +2009,32 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level, + } + else + { ++ static const WCHAR invalidW[] = { '<', '>', '\"', 0 }; ++ static const WCHAR wildcardW[] = { '*', 0 }; ++ DWORD mask_len; ++ + if (!RtlCreateUnicodeString( &info->mask, mask )) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + goto error; + } + ++ /* strip invalid characters from mask */ ++ mask_len = info->mask.Length / sizeof(WCHAR); ++ while (mask_len && strchrW(invalidW, mask[mask_len - 1])) ++ mask_len--; ++ ++ if (!mask_len) ++ { ++ strcpyW( info->mask.Buffer, wildcardW ); ++ info->mask.Length = strlenW(wildcardW) * sizeof(WCHAR); ++ } ++ else ++ { ++ info->mask.Buffer[mask_len] = 0; ++ info->mask.Length = mask_len * sizeof(WCHAR); ++ } ++ + /* truncate dir name before mask */ + *mask = 0; + nt_name.Length = (mask - nt_name.Buffer) * sizeof(WCHAR); +-- +2.7.0 + diff --git a/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch b/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch new file mode 100644 index 00000000..a4f6d9ff --- /dev/null +++ b/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch @@ -0,0 +1,135 @@ +From 29a12264fdd49cdb5b815064c2767e7fc349133b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 18:32:09 +0100 +Subject: kernel32/tests: Add tests for FindFirstFileA with invalid characters. + +Includes testcases by Vincent Pelletier. +--- + dlls/kernel32/tests/file.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 99 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index 53dc04b..a7ac09c 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -2517,11 +2517,85 @@ static char get_windows_drive(void) + return windowsdir[0]; + } + ++struct ++{ ++ const char *path; ++ BOOL expected; ++} ++static const invalid_char_tests[] = ++{ ++ { "./test-dir", TRUE }, ++ { "./test-dir/", FALSE }, ++ { ".\\test-dir", TRUE }, ++ { ".\\test-dir\\", FALSE }, ++ { "/>test-dir", FALSE }, ++ { "<\"test->dir", FALSE }, ++ { "dir", FALSE }, ++ { ">dir", FALSE }, ++ { ">>test-dir", FALSE }, ++ { ">test->dir", FALSE }, ++ { ">test-dir", FALSE }, ++ { "\"test-dir\"", FALSE }, ++ { "\"test-file\"", FALSE }, ++ { "test-/>dir", FALSE }, ++ { "test-dir/", FALSE }, ++ { "test-dir//", FALSE }, ++ { "test-dir/:", FALSE }, ++ { "test-dir/<", TRUE }, ++ { "test-dir/>", TRUE }, ++ { "test-dir/\"", TRUE }, ++ { "test-dir/\\", FALSE }, ++ { "test-dir/|", FALSE }, ++ { "test-dir<", TRUE }, ++ { "test-dir<><>\"\"\"\"<<<>", TRUE }, ++ { "test-dir<>", TRUE }, ++ { "test-dir<\"", TRUE }, ++ { "test-dir>", TRUE }, ++ { "test-dir>/", FALSE }, ++ { "test-dir><", TRUE }, ++ { "test-dir>>", TRUE }, ++ { "test-dir>\"", TRUE }, ++ { "test-dir\"", TRUE }, ++ { "test-dir\"/", FALSE }, ++ { "test-dir\"<", TRUE }, ++ { "test-dir\">", TRUE }, ++ { "test-dir\"\"", TRUE }, ++ { "test-dir\"\"\"\"\"", TRUE }, ++ { "test-dir\\", FALSE }, ++ { "test-dir\\/", FALSE }, ++ { "test-dir\\<", TRUE }, ++ { "test-dir\\>", TRUE }, ++ { "test-dir\\\"", TRUE }, ++ { "test-dir\\\\", FALSE }, ++ { "test-file/", FALSE }, ++ { "test-file/<", FALSE }, ++ { "test-file/>", FALSE }, ++ { "test-file/\"", FALSE }, ++ { "test-file<", TRUE }, ++ { "test-file<<", TRUE }, ++ { "test-file<>", TRUE }, ++ { "test-file<\"", TRUE }, ++ { "test-file>", TRUE }, ++ { "test-file><", TRUE }, ++ { "test-file>>", TRUE }, ++ { "test-file>\"", TRUE }, ++ { "test-file\"", TRUE }, ++ { "test-file\"<", TRUE }, ++ { "test-file\">", TRUE }, ++ { "test-file\"\"", TRUE }, ++ { "test-file\\", FALSE }, ++ { "test-file\\<", FALSE }, ++ { "test-file\\>", FALSE }, ++ { "test-file\\\"", FALSE }, ++}; ++ + static void test_FindFirstFileA(void) + { + HANDLE handle; + WIN32_FIND_DATAA data; +- int err; ++ int err, i; + char buffer[5] = "C:\\"; + char buffer2[100]; + char nonexistent[MAX_PATH]; +@@ -2689,6 +2763,30 @@ static void test_FindFirstFileA(void) + err = GetLastError(); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); + ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); ++ ++ /* try FindFirstFileA with invalid characters */ ++ CreateDirectoryA("test-dir", NULL); ++ _lclose(_lcreat("test-file", 0)); ++ ++ for (i = 0; i < sizeof(invalid_char_tests) / sizeof(invalid_char_tests[0]); i++) ++ { ++ handle = FindFirstFileA(invalid_char_tests[i].path, &data); ++ if (invalid_char_tests[i].expected) ++ { ++ ok(handle != INVALID_HANDLE_VALUE, "FindFirstFileA on %s should succeed\n", ++ invalid_char_tests[i].path); ++ } ++ else ++ { ++ ok(handle == INVALID_HANDLE_VALUE, "FindFirstFileA on %s should fail\n", ++ invalid_char_tests[i].path); ++ } ++ if (handle != INVALID_HANDLE_VALUE) ++ FindClose(handle); ++ } ++ ++ DeleteFileA("test-file"); ++ RemoveDirectoryA("test-dir"); + } + + static void test_FindNextFileA(void) +-- +2.7.0 + diff --git a/patches/kernel32-FindFirstFile/definition b/patches/kernel32-FindFirstFile/definition new file mode 100644 index 00000000..5c04a439 --- /dev/null +++ b/patches/kernel32-FindFirstFile/definition @@ -0,0 +1 @@ +Fixes: [22635] Strip invalid characters from mask in FindFirstFileExW diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 8c6cd9ed..f398e888 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -158,6 +158,7 @@ patch_enable_all () enable_kernel32_CompareString_Length="$1" enable_kernel32_CopyFileEx="$1" enable_kernel32_Cwd_Startup_Info="$1" + enable_kernel32_FindFirstFile="$1" enable_kernel32_FreeUserPhysicalPages="$1" enable_kernel32_GetCurrentPackageFamilyName="$1" enable_kernel32_GetFinalPathNameByHandle="$1" @@ -616,6 +617,9 @@ patch_enable () kernel32-Cwd_Startup_Info) enable_kernel32_Cwd_Startup_Info="$2" ;; + kernel32-FindFirstFile) + enable_kernel32_FindFirstFile="$2" + ;; kernel32-FreeUserPhysicalPages) enable_kernel32_FreeUserPhysicalPages="$2" ;; @@ -3904,6 +3908,23 @@ if test "$enable_kernel32_Cwd_Startup_Info" -eq 1; then ) >> "$patchlist" fi +# Patchset kernel32-FindFirstFile +# | +# | This patchset fixes the following Wine bugs: +# | * [#22635] Strip invalid characters from mask in FindFirstFileExW +# | +# | Modified files: +# | * dlls/kernel32/file.c, dlls/kernel32/tests/file.c +# | +if test "$enable_kernel32_FindFirstFile" -eq 1; then + patch_apply kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch + patch_apply kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch + ( + echo '+ { "Michael Müller", "kernel32: Strip invalid characters from mask in FindFirstFileExW.", 1 },'; + echo '+ { "Michael Müller", "kernel32/tests: Add tests for FindFirstFileA with invalid characters.", 1 },'; + ) >> "$patchlist" +fi + # Patchset kernel32-LocaleNameToLCID # | # | This patchset fixes the following Wine bugs: