Commit 6ecccdb7 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

shell32: Handle a few cases in FO_COPY that arise from not double-NULL terminating the input.

parent bed661ae
......@@ -1186,8 +1186,12 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FIL
if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->bAnyFromWildcard)
return ERROR_CANCELLED;
if (!(op->req->fFlags & FOF_MULTIDESTFILES) && flTo->dwNumFiles != 1)
if (!(op->req->fFlags & FOF_MULTIDESTFILES) &&
flFrom->dwNumFiles != 1 && flTo->dwNumFiles != 1 &&
!flFrom->bAnyFromWildcard)
{
return ERROR_CANCELLED;
}
if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->dwNumFiles != 1 &&
flFrom->dwNumFiles != flTo->dwNumFiles)
......@@ -1243,7 +1247,8 @@ static HRESULT copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FIL
}
if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
(flFrom->dwNumFiles == 1 && IsAttribDir(fileDest->attributes)))
(IsAttribDir(fileDest->attributes) &&
(flFrom->dwNumFiles == 1 || flFrom->bAnyFromWildcard)))
{
copy_to_dir(op, entryToCopy, fileDest);
}
......@@ -1537,7 +1542,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
if (ret == ERROR_CANCELLED)
lpFileOp->fAnyOperationsAborted = TRUE;
return ret;
}
......
......@@ -839,6 +839,117 @@ static void test_copy(void)
retval = SHFileOperation(&shfo);
ok(retval == 0, "Expected 0, got %d\n", retval);
ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
createTestFile("one.txt");
/* no double-NULL terminator for pFrom */
memset(from, 'a', MAX_PATH);
lstrcpyA(from, "one.txt");
shfo.pFrom = from;
shfo.pTo = "two.txt\0";
shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
todo_wine
{
ok(retval == 1148, "Expected 1148, got %d\n", retval);
}
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
createTestFile("one.txt");
/* no double-NULL terminator for pTo */
memset(to, 'a', MAX_PATH);
lstrcpyA(to, "two.txt");
shfo.pFrom = "one.txt\0";
shfo.pTo = to;
shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(DeleteFileA("two.txt"), "Expected file to exist\n");
createTestFile("one.txt");
/* no FOF_MULTIDESTFILES, two files in pTo */
shfo.pFrom = "one.txt\0";
shfo.pTo = "two.txt\0three.txt\0";
shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(DeleteFileA("two.txt"), "Expected file to exist\n");
createTestFile("one.txt");
/* no double-NULL terminator for pFrom and pTo */
memset(from, 'a', MAX_PATH);
memset(to, 'a', MAX_PATH);
lstrcpyA(from, "one.txt");
lstrcpyA(to, "two.txt");
shfo.pFrom = from;
shfo.pTo = to;
shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
todo_wine
{
ok(retval == 1148, "Expected 1148, got %d\n", retval);
}
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
createTestFile("one.txt");
/* no double-NULL terminator for pTo, FOF_MULTIDESTFILES */
memset(to, 'a', MAX_PATH);
lstrcpyA(to, "two.txt");
shfo.pFrom = "one.txt\0";
shfo.pTo = to;
shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(DeleteFileA("two.txt"), "Expected file to exist\n");
createTestFile("one.txt");
createTestFile("two.txt");
/* no double-NULL terminator for pTo,
* multiple source files, FOF_MULTIDESTFILES
*/
memset(to, 'a', 2 * MAX_PATH);
lstrcpyA(to, "three.txt");
shfo.pFrom = "one.txt\0two.txt\0";
shfo.pTo = to;
shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
ok(DeleteFileA("one.txt"), "Expected file to exist\n");
ok(DeleteFileA("two.txt"), "Expected file to exist\n");
todo_wine
{
ok(!DeleteFileA("three.txt"), "Expected file to not exist\n");
}
createTestFile("aa.txt");
createTestFile("ab.txt");
CreateDirectoryA("one", NULL);
CreateDirectoryA("two", NULL);
/* pFrom has a glob, pTo has more than one dest */
shfo.pFrom = "a*.txt\0";
shfo.pTo = "one\0two\0";
shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
retval = SHFileOperation(&shfo);
ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
}
/* tests the FO_MOVE action */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment