Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/main/java/org/codehaus/plexus/util/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,9 @@
}
directory.deleteOnExit(); // The hook reverses the list

cleanDirectoryOnExit(directory);
if (!NioFiles.isSymbolicLink(directory)) {
cleanDirectoryOnExit(directory);
}
}

/**
Expand Down Expand Up @@ -1343,7 +1345,9 @@
return;
}

cleanDirectory(directory);
if (!NioFiles.isSymbolicLink(directory)) {
cleanDirectory(directory);
}
if (!directory.delete()) {
final String message = "Directory " + directory + " unable to be deleted.";
throw new IOException(message);
Expand Down Expand Up @@ -1922,9 +1926,9 @@
fileReader = null;
} finally {
//noinspection deprecation
IOUtil.close(fileReader);

Check warning on line 1929 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-26.04 jdk-25-zulu 3.10.0

close(java.io.Reader) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1929 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-latest jdk-21-zulu 3.10.0

close(java.io.Reader) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1929 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-latest jdk-8-zulu 3.10.0

close(java.io.Reader) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1929 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / macos-latest jdk-25-zulu 3.10.0

close(java.io.Reader) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1929 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-latest jdk-25-zulu 3.10.0

close(java.io.Reader) in org.codehaus.plexus.util.IOUtil has been deprecated
//noinspection deprecation
IOUtil.close(fileWriter);

Check warning on line 1931 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-26.04 jdk-25-zulu 3.10.0

close(java.io.Writer) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1931 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-latest jdk-21-zulu 3.10.0

close(java.io.Writer) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1931 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-latest jdk-8-zulu 3.10.0

close(java.io.Writer) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1931 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / macos-latest jdk-25-zulu 3.10.0

close(java.io.Writer) in org.codehaus.plexus.util.IOUtil has been deprecated

Check warning on line 1931 in src/main/java/org/codehaus/plexus/util/FileUtils.java

View workflow job for this annotation

GitHub Actions / Build it / Verify / ubuntu-latest jdk-25-zulu 3.10.0

close(java.io.Writer) in org.codehaus.plexus.util.IOUtil has been deprecated
}
} else {
if (isSourceNewerThanDestination(from, to) || overwrite) {
Expand Down
63 changes: 63 additions & 0 deletions src/test/java/org/codehaus/plexus/util/FileUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.assumeFalse;

/**
* This is used to test FileUtils for correctness.
Expand Down Expand Up @@ -1185,6 +1188,66 @@ void deleteDirectoryWithDanglingSymlink() throws Exception {
assertFalse(getTestDirectory().exists(), "Failed to delete test directory");
}

@Test
@DisabledOnOs(OS.WINDOWS)
void deleteDirectoryDoesNotFollowDirSymlink() throws Exception {
File outside = new File(getTestDirectory(), "outside");
outside.mkdir();
File outsideFile = new File(outside, "keep.txt");
createFile(outsideFile, 1);

File directory = new File(getTestDirectory(), "directory");
File readOnly = new File(directory, "readOnly");
readOnly.mkdirs();
File symlink = new File(readOnly, "dirSymlink");
createSymlink(symlink, outside);
// the symlink cannot be unlinked from a read-only directory
readOnly.setWritable(false);
try {
assumeFalse(Files.isWritable(readOnly.toPath()), "directory permissions are not enforced");
assertThrows(IOException.class, () -> FileUtils.deleteDirectory(directory));
} finally {
readOnly.setWritable(true);
symlink.delete();
}
assertTrue(outsideFile.exists(), "deleteDirectory followed a symlink out of the directory");
}

@Test
@DisabledOnOs(OS.WINDOWS)
void forceDeleteOnExitDoesNotFollowDirSymlink() throws Exception {
File outside = new File(getTestDirectory(), "outside");
outside.mkdir();
File outsideFile = new File(outside, "keep.txt");
createFile(outsideFile, 1);

File directory = new File(getTestDirectory(), "directory");
directory.mkdir();
createSymlink(new File(directory, "dirSymlink"), outside);

// deleteOnExit only runs when the JVM exits, so run it in a separate one
String java = new File(System.getProperty("java.home"), "bin/java").getPath();
Process process = new ProcessBuilder(
java,
"-cp",
System.getProperty("java.class.path"),
ForceDeleteOnExit.class.getName(),
directory.getAbsolutePath())
.inheritIO()
.start();
assertTrue(process.waitFor(1, TimeUnit.MINUTES), "JVM did not exit");
assertEquals(0, process.exitValue());

assertFalse(directory.exists(), "Failed to delete directory on exit");
assertTrue(outsideFile.exists(), "forceDeleteOnExit followed a symlink out of the directory");
}

public static final class ForceDeleteOnExit {
public static void main(String[] args) throws IOException {
FileUtils.forceDeleteOnExit(new File(args[0]));
}
}

@Test
void testcopyDirectoryLayoutWithExcludesIncludes() throws Exception {
File destination = new File("target", "copyDirectoryStructureWithExcludesIncludes");
Expand Down
Loading