Author: bodewig
Date: Sat Jan  4 16:20:00 2014
New Revision: 1555363

URL: http://svn.apache.org/r1555363
Log:
Don't delete the target if copy failed because the target was read-only.  PR 
53095

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java
    ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java
    ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml

Modified: ant/core/trunk/WHATSNEW
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=1555363&r1=1555362&r2=1555363&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Sat Jan  4 16:20:00 2014
@@ -64,6 +64,10 @@ Fixed bugs:
  * reading of compiler args has become more defensive
    Bugzilla Report 53754
 
+ * <copy> without force="true" would not only fail to overwrite a
+   read-only file as expected but also remove the existing file.
+   Bugzilla Report 53095
+
 Other changes:
 --------------
 

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java?rev=1555363&r1=1555362&r2=1555363&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java Sat Jan  4 
16:20:00 2014
@@ -898,7 +898,9 @@ public class Copy extends Task {
                         String msg = "Failed to copy " + fromFile + " to " + 
toFile
                             + " due to " + getDueTo(ioe);
                         File targetFile = new File(toFile);
-                        if (targetFile.exists() && !targetFile.delete()) {
+                        if (!(ioe instanceof
+                              ResourceUtils.ReadOnlyTargetFileException)
+                            && targetFile.exists() && !targetFile.delete()) {
                             msg += " and I couldn't delete the corrupt " + 
toFile;
                         }
                         if (failonerror) {
@@ -980,7 +982,9 @@ public class Copy extends Task {
                             + " to " + toFile
                             + " due to " + getDueTo(ioe);
                         File targetFile = new File(toFile);
-                        if (targetFile.exists() && !targetFile.delete()) {
+                        if (!(ioe instanceof
+                              ResourceUtils.ReadOnlyTargetFileException)
+                            && targetFile.exists() && !targetFile.delete()) {
                             msg += " and I couldn't delete the corrupt " + 
toFile;
                         }
                         if (failonerror) {

Modified: ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java?rev=1555363&r1=1555362&r2=1555363&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java 
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java Sat 
Jan  4 16:20:00 2014
@@ -406,8 +406,7 @@ public class ResourceUtils {
         }
         if (destFile != null && destFile.isFile() && !destFile.canWrite()) {
             if (!force) {
-                throw new IOException("can't write to read-only destination "
-                                      + "file " + destFile);
+                throw new ReadOnlyTargetFileException(destFile);
             } else if (!FILE_UTILS.tryHardToDelete(destFile)) {
                 throw new IOException("failed to delete read-only "
                                       + "destination file " + destFile);
@@ -785,4 +784,13 @@ public class ResourceUtils {
     public static interface ResourceSelectorProvider {
         ResourceSelector getTargetSelectorForSource(Resource source);
     }
+
+    /**
+     * @since Ant 1.9.4
+     */
+    public static class ReadOnlyTargetFileException extends IOException {
+        public ReadOnlyTargetFileException(File destFile) {
+            super("can't write to read-only destination file " + destFile);
+        }
+    }
 }

Modified: ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml?rev=1555363&r1=1555362&r2=1555363&view=diff
==============================================================================
--- ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml (original)
+++ ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml Sat Jan  4 16:20:00 
2014
@@ -446,4 +446,26 @@ public class NullByteStreamResource exte
     <au:assertResourceDoesntContain resource="${input}/somefile"
                                     value="default contents"/>
   </target>
+
+  <target name="testCopyDoesntDeleteReadonlyTargetWhenCopyFails"
+          
description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53095";>
+    <mkdir dir="${input}"/>
+    <mkdir dir="${output}"/>
+    <touch file="${input}/somefile"/>
+    <touch file="${output}/somefile"/>
+    <exec executable="chmod" osfamily="unix">
+      <arg value="-w"/>
+      <arg file="${output}/somefile"/>
+    </exec>
+    <exec executable="attrib" osfamily="dos">
+      <arg value="+r"/>
+      <arg file="${output}/somefile"/>
+    </exec>
+    <au:expectfailure>
+      <copy todir="${output}" file="${input}/somefile"
+            overwrite="true"/>
+    </au:expectfailure>
+    <au:assertFileExists file="${input}/somefile"/>
+    <au:assertFileExists file="${output}/somefile"/>
+  </target>
 </project>


Reply via email to