diff --git a/os/src/ZipOps.scala b/os/src/ZipOps.scala index e8ee40a0..14fad6fd 100644 --- a/os/src/ZipOps.scala +++ b/os/src/ZipOps.scala @@ -360,10 +360,10 @@ object unzip { } else null if (zipEntry.isDirectory) { - os.makeDir.all(newFile, perms = perms) - if (perms != null && os.perms(newFile) != perms) { - // because of umask - os.perms.set(newFile, perms) + os.makeDir.all(newFile) + if (perms != null) { + // make sure directories at least have OWNER_EXECUTE + os.perms.set(newFile, perms + PosixFilePermission.OWNER_EXECUTE) } } else if (isSymLink) { val target = scala.io.Source.fromInputStream(zipInputStream).mkString diff --git a/os/test/src/ZipOpTests.scala b/os/test/src/ZipOpTests.scala index 3462e550..afa61d0a 100644 --- a/os/test/src/ZipOpTests.scala +++ b/os/test/src/ZipOpTests.scala @@ -5,6 +5,7 @@ import test.os.TestUtil.prep import utest._ import java.io.{ByteArrayInputStream, ByteArrayOutputStream, PrintStream} +import java.nio.file.attribute.PosixFilePermission import java.util.zip.{ZipEntry, ZipOutputStream} object ZipOpTests extends TestSuite { @@ -537,5 +538,25 @@ object ZipOpTests extends TestSuite { assert(file2Content == "Content of file2") } + test("unzipDirectoryEnsureExecutablePermission") - prep { wd => + if (!scala.util.Properties.isWin) { + val zipFileName = "zipDirExecutable" + val source = wd / "folder1" + val dir = source / "dir" + + os.makeDir(dir) + val perms = os.perms(dir) + os.perms.set(dir, perms - PosixFilePermission.OWNER_EXECUTE) + + val zipped = os.zip( + dest = wd / s"$zipFileName.zip", + sources = Seq(source) + ) + + val unzipped = os.unzip(zipped, dest = wd / zipFileName) + assert(os.perms(unzipped / "dir").contains(PosixFilePermission.OWNER_EXECUTE)) + assert(os.perms(unzipped / "dir") == perms) + } + } } }