Skip to content

Commit 167effd

Browse files
committed
IO-692: Fix PathUtils.deleteFile() on symbolic links pointing to non-existing files
1 parent 2bc7e31 commit 167effd

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

src/changes/changes.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ The <action> type attribute can be add,update,fix,remove.
7474
<action dev="ggregory" type="fix" due-to="Gary Gregory">
7575
FileUtils.forceDelete(File) actually forces deletion of read-only files as it did in version 2.6.
7676
</action>
77+
<action issue="IO-692" dev="ebourg" type="fix" due-to="Matthew Rooney, Emmanuel Bourg">
78+
PathUtils.deleteFile() no longer throws a NoSuchFileException when applied on a symbolic link pointing
79+
to a file that doesn't exist.
80+
</action>
7781
<!-- ADD -->
7882
<action dev="ggregory" type="add" due-to="Gary Gregory">
7983
Add FileSystemProviders class.

src/main/java/org/apache/commons/io/file/PathUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ public static PathCounters deleteFile(final Path file, final LinkOption[] linkOp
481481
}
482482
final PathCounters pathCounts = Counters.longPathCounters();
483483
final boolean exists = Files.exists(file, linkOptions);
484-
final long size = exists ? Files.size(file) : 0;
484+
final long size = exists && !Files.isSymbolicLink(file) ? Files.size(file) : 0;
485485
if (overrideReadOnly(deleteOptions) && exists) {
486486
setReadOnly(file, false, linkOptions);
487487
}

src/test/java/org/apache/commons/io/file/PathUtilsDeleteFileTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
import static org.apache.commons.io.file.CounterAssertions.assertCounts;
2121
import static org.junit.jupiter.api.Assertions.assertFalse;
2222
import static org.junit.jupiter.api.Assertions.assertThrows;
23+
import static org.junit.jupiter.api.Assertions.assertTrue;
24+
import static org.junit.jupiter.api.Assumptions.assumeFalse;
2325
import java.io.IOException;
2426
import java.nio.file.Files;
27+
import java.nio.file.LinkOption;
2528
import java.nio.file.NoSuchFileException;
2629
import java.nio.file.Path;
2730
import java.nio.file.Paths;
@@ -142,4 +145,20 @@ public void testSetReadOnlyFileDirectory1FileSize1() throws IOException {
142145
// This will throw if not empty.
143146
Files.deleteIfExists(tempDir);
144147
}
148+
149+
@Test
150+
public void testDeleteBrokenLink() throws IOException {
151+
assumeFalse(SystemUtils.IS_OS_WINDOWS);
152+
153+
Path missingFile = tempDir.resolve("missing.txt");
154+
Path brokenLink = tempDir.resolve("broken.txt");
155+
Files.createSymbolicLink(brokenLink, missingFile);
156+
157+
assertTrue(Files.exists(brokenLink, LinkOption.NOFOLLOW_LINKS));
158+
assertFalse(Files.exists(missingFile, LinkOption.NOFOLLOW_LINKS));
159+
160+
PathUtils.deleteFile(brokenLink);
161+
162+
assertFalse(Files.exists(brokenLink, LinkOption.NOFOLLOW_LINKS), "Symbolic link not removed");
163+
}
145164
}

0 commit comments

Comments
 (0)