summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bodewig <bodewig@apache.org>2023-03-18 10:42:58 +0100
committerStefan Bodewig <bodewig@apache.org>2023-03-18 10:42:58 +0100
commitbb02a4d806652d6e01e8eb1b74fc74d5c94b3317 (patch)
tree1182a3ae5ed8d0d0e94c77ba9a6c5a5ecc2b673f
parent77f3ec9e842130d26a7413c1332d85b8aeee51dc (diff)
downloadant-bb02a4d806652d6e01e8eb1b74fc74d5c94b3317.tar.gz
try to preserve file permissions of exisiting target when renaming
https://bz.apache.org/bugzilla/show_bug.cgi?id=66522
-rw-r--r--WHATSNEW4
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/FixCRLF.java2
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/Replace.java2
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java2
-rw-r--r--src/main/org/apache/tools/ant/util/FileUtils.java33
-rw-r--r--src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java34
6 files changed, 74 insertions, 3 deletions
diff --git a/WHATSNEW b/WHATSNEW
index cd2d2bcfc..267b0d549 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -18,6 +18,10 @@ Fixed bugs:
This is now fixed.
Bugzilla Report 66468
+ * <fixcrlf>, <replace> and <replaceregexp> now try to preserve the
+ file permissions of the files they modify.
+ Bugzilla Report 66522
+
Other changes:
--------------
diff --git a/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java b/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
index cff7ed820..82f7843ba 100644
--- a/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
+++ b/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
@@ -372,7 +372,7 @@ public class FixCRLF extends MatchingTask implements ChainableReader {
Project.MSG_DEBUG);
}
if (destIsWrong) {
- FILE_UTILS.rename(tmpFile, destFile);
+ FILE_UTILS.rename(tmpFile, destFile, true);
if (preserveLastModified) {
log("preserved lastModified for " + destFile,
Project.MSG_DEBUG);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Replace.java b/src/main/org/apache/tools/ant/taskdefs/Replace.java
index 66cdef43b..a7daa0370 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Replace.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Replace.java
@@ -670,7 +670,7 @@ public class Replace extends MatchingTask {
if (changes) {
fileCount++;
long origLastModified = src.lastModified();
- FILE_UTILS.rename(temp, src);
+ FILE_UTILS.rename(temp, src, true);
if (preserveLastModified) {
FILE_UTILS.setFileLastModified(src, origLastModified);
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
index 5b7e3e695..c5b9d7d43 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
@@ -434,7 +434,7 @@ public class ReplaceRegExp extends Task {
log("File has changed; saving the updated file", Project.MSG_VERBOSE);
try {
long origLastModified = f.lastModified();
- FILE_UTILS.rename(temp, f);
+ FILE_UTILS.rename(temp, f, true);
if (preserveLastModified) {
FILE_UTILS.setFileLastModified(f, origLastModified);
}
diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java
index 0deecaa7c..150bf5f85 100644
--- a/src/main/org/apache/tools/ant/util/FileUtils.java
+++ b/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -40,6 +40,7 @@ import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
+import java.lang.UnsupportedOperationException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -48,6 +49,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Random;
+import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;
@@ -1450,6 +1452,27 @@ public class FileUtils {
* @since Ant 1.6
*/
public void rename(File from, File to) throws IOException {
+ rename(from, to, false);
+ }
+
+ /**
+ * Renames a file, even if that involves crossing file system boundaries.
+ *
+ * <p>This will remove <code>to</code> (if it exists), ensure that
+ * <code>to</code>'s parent directory exists and move
+ * <code>from</code>, which involves deleting <code>from</code> as
+ * well.</p>
+ *
+ * @param from the file to move.
+ * @param to the new file name.
+ * @param keepTargetFilePermissions keep target file permissions
+ * @throws IOException if anything bad happens during this
+ * process. Note that <code>to</code> may have been deleted
+ * already when this happens.
+ * @since Ant 1.6
+ */
+ public void rename(File from, File to, boolean keepTargetFilePermissions) throws IOException {
+ Set<PosixFilePermission> existingFilePermissions = null;
// identical logic lives in Move.renameFile():
from = normalize(from.getAbsolutePath()).getCanonicalFile();
to = normalize(to.getAbsolutePath());
@@ -1461,6 +1484,13 @@ public class FileUtils {
System.err.println("Rename of " + from + " to " + to + " is a no-op.");
return;
}
+ if (keepTargetFilePermissions) {
+ try {
+ existingFilePermissions = Files.getPosixFilePermissions(to.toPath());
+ } catch (UnsupportedOperationException | IOException exc) {
+ //ignore
+ }
+ }
if (to.exists() && !(areSame(from, to) || tryHardToDelete(to))) {
throw new IOException("Failed to delete " + to + " while trying to rename " + from);
}
@@ -1476,6 +1506,9 @@ public class FileUtils {
throw new IOException("Failed to delete " + from + " while trying to rename it.");
}
}
+ if (existingFilePermissions != null) {
+ Files.setPosixFilePermissions(to.toPath(), existingFilePermissions);
+ }
}
/**
diff --git a/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java b/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
index 555916cac..5a168a514 100644
--- a/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
+++ b/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
@@ -26,6 +26,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
@@ -119,6 +120,39 @@ public class FileUtilsTest {
assertNotEquals(thirdModTime, secondModTime);
}
+ /**
+ * test file permissions for FileUtils#rename.
+ * Since Ant1.10.7, ant uses FileUtils#rename for various tasks (eg. ReplaceRegExp).
+ * Test that file permission set stays the same.
+ * @see FileUtils#rename(java.io.File, java.io.File, boolean)
+ * @throws IOException if something goes wrong
+ */
+ @Test
+ public void testFilePermissions() throws IOException {
+ assumeFalse("Test doesn't run on DOS", Os.isFamily("dos"));
+ File removeThis = getFileUtils().createTempFile("permis", "sion", folder.getRoot(), true, true);
+ File toBeMoved1 = getFileUtils().createTempFile("permis", "sion", folder.getRoot(), true, true);
+ File toBeMoved2 = getFileUtils().createTempFile("permis", "sion", folder.getRoot(), true, true);
+ try (FileOutputStream fos = new FileOutputStream(removeThis)) {
+ fos.write(new byte[0]);
+ }
+ try (FileOutputStream fos = new FileOutputStream(toBeMoved1)) {
+ fos.write(new byte[0]);
+ }
+ try (FileOutputStream fos = new FileOutputStream(toBeMoved2)) {
+ fos.write(new byte[0]);
+ }
+ Set<PosixFilePermission> allAllowed = PosixFilePermissions.fromString("rwxrwxrwx");
+ Files.setPosixFilePermissions(removeThis.toPath(), allAllowed);
+
+ getFileUtils().rename(toBeMoved1, removeThis, true);
+ assertEquals(allAllowed,Files.getPosixFilePermissions(removeThis.toPath()));
+
+ Set<PosixFilePermission> tempAllowed = Files.getPosixFilePermissions(toBeMoved2.toPath());
+ getFileUtils().rename(toBeMoved2, removeThis);
+ assertEquals(tempAllowed,Files.getPosixFilePermissions(removeThis.toPath()));
+ }
+
@Test
public void testResolveFilePosix() {
assumeTrue("DOS or NetWare", !Os.isFamily("dos") && !Os.isFamily("netware"));