From 6fde3391d3661e49c6595d9b6cdd28cb448ba006 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Tue, 2 Aug 2022 00:57:20 +0300 Subject: [PATCH] Test that Path.copyTo() does not follow symlink in destination --- .../stdlib/jdk7/test/PathExtensionsTest.kt | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/libraries/stdlib/jdk7/test/PathExtensionsTest.kt b/libraries/stdlib/jdk7/test/PathExtensionsTest.kt index b7f69b8c168..3c91a8c855e 100644 --- a/libraries/stdlib/jdk7/test/PathExtensionsTest.kt +++ b/libraries/stdlib/jdk7/test/PathExtensionsTest.kt @@ -198,6 +198,123 @@ class PathExtensionsTest : AbstractPathTest() { } } + @Test + fun copyToSymlinkDestination() { + val root = createTempDirectory("copyTo-root").cleanupRecursively() + val targetFile = createTempFile(root, "targetFile").also { it.writeText("target file") } + val targetDirectory = createTempDirectory(root, "targetDirectory").also { it.resolve("a").createFile() } + + // copy file + val srcFile = createTempFile(root, "srcFile").also { it.writeText("source file") } + val dstFile = root.resolve("dstFile").tryCreateSymbolicLinkTo(targetFile) ?: return + + assertFailsWith { + srcFile.copyTo(dstFile) + } + assertFailsWith { + srcFile.copyTo(dstFile, LinkOption.NOFOLLOW_LINKS) + } + assertTrue(dstFile.isSymbolicLink()) + assertEquals("target file", dstFile.readText()) + + // copy directory + val srcDirectory = createTempDirectory(root, "srcDirectory") + val dstDirectory = root.resolve("dstDirectory").tryCreateSymbolicLinkTo(targetDirectory) ?: return + + assertFailsWith { + srcDirectory.copyTo(dstDirectory) + } + assertFailsWith { + srcDirectory.copyTo(dstDirectory, LinkOption.NOFOLLOW_LINKS) + } + assertTrue(dstDirectory.isSymbolicLink()) + assertEquals("a", dstDirectory.listDirectoryEntries().single().name) + + // overwrite file + srcFile.copyTo(dstFile, overwrite = true) + assertFalse(dstFile.isSymbolicLink()) + assertEquals("source file", dstFile.readText()) + assertEquals("target file", targetFile.readText()) + + dstFile.deleteExisting() + dstFile.tryCreateSymbolicLinkTo(targetFile)!! + srcFile.copyTo(dstFile, StandardCopyOption.REPLACE_EXISTING, LinkOption.NOFOLLOW_LINKS) + assertFalse(dstFile.isSymbolicLink()) + assertEquals("source file", dstFile.readText()) + assertEquals("target file", targetFile.readText()) + + // overwrite directory + srcDirectory.copyTo(dstDirectory, overwrite = true) + assertFalse(dstDirectory.isSymbolicLink()) + assertEquals(emptyList(), dstDirectory.listDirectoryEntries()) + assertEquals("a", targetDirectory.listDirectoryEntries().single().name) + + dstDirectory.deleteExisting() + dstDirectory.tryCreateSymbolicLinkTo(targetDirectory)!! + srcDirectory.copyTo(dstDirectory, StandardCopyOption.REPLACE_EXISTING, LinkOption.NOFOLLOW_LINKS) + assertFalse(dstDirectory.isSymbolicLink()) + assertEquals(emptyList(), dstDirectory.listDirectoryEntries()) + assertEquals("a", targetDirectory.listDirectoryEntries().single().name) + } + + @Test + fun copyToBrokenSymlinkDestination() { + val root = createTempDirectory("copyTo-root").cleanupRecursively() + val symlinkTarget = root.resolve("target") + + // copy file + val srcFile = createTempFile(root, "srcFile").also { it.writeText("source file") } + val dstFile = root.resolve("dstFile").tryCreateSymbolicLinkTo(symlinkTarget) ?: return + + assertFailsWith { + srcFile.copyTo(dstFile) + } + assertFailsWith { + srcFile.copyTo(dstFile, LinkOption.NOFOLLOW_LINKS) + } + assertTrue(dstFile.isSymbolicLink()) + assertFailsWith { + dstFile.readText() + } + + // copy directory + val srcDirectory = createTempDirectory(root, "srcDirectory") + val dstDirectory = root.resolve("dstDirectory").tryCreateSymbolicLinkTo(symlinkTarget) ?: return + + assertFailsWith { + srcDirectory.copyTo(dstDirectory) + } + assertFailsWith { + srcDirectory.copyTo(dstDirectory, LinkOption.NOFOLLOW_LINKS) + } + assertTrue(dstDirectory.isSymbolicLink()) + assertFailsWith { // Fails with NoSuchFileException in Unix, NotDirectoryException in Windows. + dstDirectory.listDirectoryEntries() + } + + // overwrite file + srcFile.copyTo(dstFile, overwrite = true) + assertFalse(dstFile.isSymbolicLink()) + assertEquals("source file", dstFile.readText()) + + dstFile.deleteExisting() + dstFile.tryCreateSymbolicLinkTo(symlinkTarget)!! + srcFile.copyTo(dstFile, StandardCopyOption.REPLACE_EXISTING, LinkOption.NOFOLLOW_LINKS) + assertFalse(dstFile.isSymbolicLink()) + assertEquals("source file", dstFile.readText()) + + // overwrite directory + srcDirectory.copyTo(dstDirectory, overwrite = true) + assertFalse(dstDirectory.isSymbolicLink()) + assertEquals(emptyList(), dstDirectory.listDirectoryEntries()) + + dstDirectory.deleteExisting() + dstDirectory.tryCreateSymbolicLinkTo(symlinkTarget)!! + srcDirectory.copyTo(dstDirectory, StandardCopyOption.REPLACE_EXISTING, LinkOption.NOFOLLOW_LINKS) + assertFalse(dstDirectory.isSymbolicLink()) + assertEquals(emptyList(), dstDirectory.listDirectoryEntries()) + } + @Test fun copyToNameWithoutParent() { val currentDir = Path("").absolute()