[PATCH] cmd: Fix copying when the dest is one of the sources.

Lauri Kenttä lauri.kentta at gmail.com
Sat Nov 26 14:07:53 CST 2016


"COPY a+b a" appends b to a.
"COPY a+b b" skips b from the sources.
(Previously Wine just fails.)

Fixes the main issue of bug 35495.

Signed-off-by: Lauri Kenttä <lauri.kentta at gmail.com>
---
 programs/cmd/builtins.c                  | 19 +++++++++++++++----
 programs/cmd/tests/test_builtins.cmd     | 15 +++++++++++++++
 programs/cmd/tests/test_builtins.cmd.exp |  3 +++
 3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index a29a502..3b6603c 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -922,6 +922,7 @@ void WCMD_copy(WCHAR * args) {
       do {
         WCHAR outname[MAX_PATH];
         BOOL  overwrite;
+        BOOL  appendtofirstfile = FALSE;
 
         /* Skip . and .., and directories */
         if (!srcisdevice && fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
@@ -929,8 +930,9 @@ void WCMD_copy(WCHAR * args) {
         } else {
 
           /* Build final destination name */
-          strcpyW(outname, destination->name);
-          if (destisdirectory || appendfirstsource) strcatW(outname, srcname);
+          strcpyW(destname, destination->name);
+          if (destisdirectory || appendfirstsource) strcatW(destname, srcname);
+          GetFullPathNameW(destname, sizeof(outname)/sizeof(WCHAR), outname, NULL);
 
           /* Build source name */
           if (!srcisdevice) strcpyW(filenamepart, srcname);
@@ -946,8 +948,14 @@ void WCMD_copy(WCHAR * args) {
           WINE_TRACE("Flags: srcbinary(%d), dstbinary(%d), over(%d), prompt(%d)\n",
                      thiscopy->binarycopy, destination->binarycopy, overwrite, prompt);
 
+          if (!writtenoneconcat) {
+            appendtofirstfile = anyconcats && strcmpW(srcpath, outname) == 0;
+          }
+
           /* Prompt before overwriting */
-          if (!overwrite) {
+          if (appendtofirstfile) {
+            overwrite = TRUE;
+          } else if (!overwrite) {
             DWORD attributes = GetFileAttributesW(outname);
             if (attributes != INVALID_FILE_ATTRIBUTES) {
               WCHAR* question;
@@ -969,7 +977,10 @@ void WCMD_copy(WCHAR * args) {
 
           /* Do the copy as appropriate */
           if (overwrite) {
-            if (anyconcats && writtenoneconcat) {
+            if (anyconcats && strcmpW(srcpath, outname) == 0) {
+              /* Silently skip if the destination file is also a source file */
+              status = TRUE;
+            } else if (anyconcats && writtenoneconcat) {
               if (thiscopy->binarycopy) {
                 status = WCMD_ManualCopy(srcpath, outname, FALSE, TRUE);
               } else {
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index cf32481..2a706b4 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -2476,6 +2476,21 @@ rem Concat 2 files, default mode - (one EOF on the end 5+8+1)
 copy ..\file1+..\file2 file12_eof2 >nul 2>&1
 call :CheckFileSize file12_eof2 14
 
+rem Concat file1+file2+file3 into file1, should produce file1+file2+file3 = 24
+copy /y ..\file? .\ >nul 2>&1
+copy /y /b file1+file2+file3 file1 >nul 2>&1
+call :CheckFileSize file1 24
+
+rem Concat file1+file2+file3 into file2, should produce file1+file3 = 16
+copy /y ..\file? .\ >nul 2>&1
+copy /y /b file1+file2+file3 file2 >nul 2>&1
+call :CheckFileSize file2 16
+
+rem Concat file1+file2+file3 into file3, should produce file1+file2 = 13
+copy /y ..\file? .\ >nul 2>&1
+copy /y /b file1+file2+file3 file3 >nul 2>&1
+call :CheckFileSize file3 13
+
 rem --------------------------------------------------------------
 rem Show ascii source copy stops at first EOF, binary does the lot
 rem --------------------------------------------------------------
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 58f6fae..7e5b3a1 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -1384,6 +1384,9 @@ Passed: file size check on file3_plus_eof [12]@or_broken at Skipping file size chec
 Passed: file size check on file12_plus_eof [14]@or_broken at Skipping file size check on NT4
 Passed: file size check on file12_no_eof [13]@or_broken at Skipping file size check on NT4
 Passed: file size check on file12_eof2 [14]@or_broken at Skipping file size check on NT4
+Passed: file size check on file1 [24]@or_broken at Skipping file size check on NT4
+Passed: file size check on file2 [16]@or_broken at Skipping file size check on NT4
+Passed: file size check on file3 [13]@or_broken at Skipping file size check on NT4
 Passed: file size check on file1_binary_srccopy [6]@or_broken at Skipping file size check on NT4
 Passed: file size check on file1_ascii_srccopy [5]@or_broken at Skipping file size check on NT4
 Passed: file size check on file123_default_copy [25]@or_broken at Skipping file size check on NT4
-- 
2.10.2




More information about the wine-patches mailing list