From 6ddb0326bbe2db883debb50aba497fc13b18ee82 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Tue, 2 Aug 2022 00:55:54 +0300 Subject: [PATCH] Test that Path.copyTo() copies the source file access permissions --- .../stdlib/jdk7/test/AbstractPathTest.kt | 16 +++++- .../stdlib/jdk7/test/PathExtensionsTest.kt | 51 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/libraries/stdlib/jdk7/test/AbstractPathTest.kt b/libraries/stdlib/jdk7/test/AbstractPathTest.kt index 4199d74e67a..6111127f826 100644 --- a/libraries/stdlib/jdk7/test/AbstractPathTest.kt +++ b/libraries/stdlib/jdk7/test/AbstractPathTest.kt @@ -61,7 +61,7 @@ abstract class AbstractPathTest { } } - fun withRestrictedRead(vararg paths: Path, block: () -> Unit) { + fun withRestrictedRead(vararg paths: Path, alsoReset: List = emptyList(), block: () -> Unit) { try { if (paths.all { it.toFile().setReadable(false) }) { block() @@ -70,6 +70,20 @@ abstract class AbstractPathTest { } } finally { paths.forEach { it.toFile().setReadable(true) } + alsoReset.forEach { it.toFile().setReadable(true) } + } + } + + fun withRestrictedWrite(vararg paths: Path, alsoReset: List = emptyList(), block: () -> Unit) { + try { + if (paths.all { it.toFile().setWritable(false) }) { + block() + } else { + System.err.println("Couldn't restrict write access") + } + } finally { + paths.forEach { it.toFile().setWritable(true) } + alsoReset.forEach { it.toFile().setWritable(true) } } } } diff --git a/libraries/stdlib/jdk7/test/PathExtensionsTest.kt b/libraries/stdlib/jdk7/test/PathExtensionsTest.kt index d65c0407349..b7f69b8c168 100644 --- a/libraries/stdlib/jdk7/test/PathExtensionsTest.kt +++ b/libraries/stdlib/jdk7/test/PathExtensionsTest.kt @@ -147,6 +147,57 @@ class PathExtensionsTest : AbstractPathTest() { } } + @Test + fun copyToRestrictedReadSource() { + val root = createTempDirectory("copyTo-root").cleanupRecursively() + + // copy file + val srcFile = createTempFile(root, "srcFile") + val dstFile = root.resolve("dstFile") + + withRestrictedRead(srcFile, alsoReset = listOf(dstFile)) { + assertFailsWith { srcFile.copyTo(dstFile) } // fails to copy restricted file + } + + // copy directory + val srcDirectory = createTempDirectory(root, "srcDirectory") + val dstDirectory = root.resolve("dstDirectory") + + withRestrictedRead(srcDirectory, alsoReset = listOf(dstDirectory)) { + srcDirectory.copyTo(dstDirectory) // successfully copies restricted directory + assertFalse(dstDirectory.isReadable()) // copies access permissions + } + } + + @Test + fun copyToRestrictedWriteDestination() { + val root = createTempDirectory("copyTo-root").cleanupRecursively() + + // copy file + val srcFile = createTempFile(root, "srcFile") + val dstFile = createTempFile(root, "dstFile") + + withRestrictedWrite(dstFile) { + assertFailsWith { srcFile.copyTo(dstFile) } + try { + srcFile.copyTo(dstFile, overwrite = true) // successfully overwrites restricted file in Unix + assertTrue(dstFile.isWritable()) // copies access permissions + } catch (_: AccessDeniedException) { + // Windows does not allow to overwrite readonly file + } + } + + // copy directory + val srcDirectory = createTempDirectory(root, "srcDirectory") + val dstDirectory = createTempDirectory(root, "dstDirectory") + + withRestrictedWrite(dstDirectory) { + assertFailsWith { srcDirectory.copyTo(dstDirectory) } + srcDirectory.copyTo(dstDirectory, overwrite = true) // successfully overwrites restricted directory + assertTrue(dstDirectory.isWritable()) // copies access permissions + } + } + @Test fun copyToNameWithoutParent() { val currentDir = Path("").absolute()