[platform] lifting Decompressor's symlink target scope checks

... because inconvenient and incomplete

GitOrigin-RevId: 4de4c0c6ee1abaf962e89c9dafdc88e62855f606
This commit is contained in:
Roman Shevchenko
2020-05-13 10:50:44 +00:00
committed by intellij-monorepo-bot
parent f5425ef66f
commit a3e127d72d
2 changed files with 12 additions and 34 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.io;
import com.intellij.openapi.util.Condition;
@@ -17,6 +17,8 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.List;
@@ -296,12 +298,17 @@ public abstract class Decompressor {
break;
case SYMLINK:
if (StringUtil.isEmpty(entry.linkTarget) ||
!FileUtil.isAncestor(outputDir, new File(FileUtil.toCanonicalPath(outputFile.getParent() + '/' + entry.linkTarget)), true)) {
if (StringUtil.isEmpty(entry.linkTarget)) {
throw new IOException("Invalid symlink entry: " + entry.name + " -> " + entry.linkTarget);
}
FileUtil.createParentDirs(outputFile);
Files.createSymbolicLink(outputFile.toPath(), Paths.get(entry.linkTarget));
try {
Path outputTarget = Paths.get(entry.linkTarget);
FileUtil.createParentDirs(outputFile);
Files.createSymbolicLink(outputFile.toPath(), outputTarget);
}
catch (InvalidPathException e) {
throw new IOException("Invalid symlink entry: " + entry.name + " -> " + entry.linkTarget, e);
}
break;
}
@@ -197,24 +197,6 @@ class DecompressorTest {
assertThat(File(dir, "links/ok").toPath()).isSymbolicLink().hasSameBinaryContentAs(File(dir, "f").toPath())
}
@Test fun tarRogueSymlinks() {
assumeSymLinkCreationIsSupported()
val tar = tempDir.newFile("test.tar")
TarArchiveOutputStream(FileOutputStream(tar)).use { writeEntry(it, "rogue", link = "../f") }
val dir = tempDir.newDirectory("unpacked")
testNoTraversal(Decompressor.Tar(tar).withSymlinks(), dir, File(dir, "rogue"))
}
@Test fun zipRogueSymlinks() {
assumeSymLinkCreationIsSupported()
val zip = tempDir.newFile("test.zip")
ZipArchiveOutputStream(FileOutputStream(zip)).use { writeEntry(it, "rogue", link = "../f") }
val dir = tempDir.newDirectory("unpacked")
testNoTraversal(Decompressor.Zip(zip).withUnixPermissionsAndSymlinks(), dir, File(dir, "rogue"))
}
@Test fun prefixPathsFilesInZip() {
val zip = tempDir.newFile("test.zip")
ZipOutputStream(FileOutputStream(zip)).use {
@@ -362,17 +344,6 @@ class DecompressorTest {
assertThat(File(dir, "links/ok").toPath()).isSymbolicLink().hasSameBinaryContentAs(File(dir, "f").toPath())
}
@Test fun prefixPathRogueSymlinks() {
assumeSymLinkCreationIsSupported()
val tar = tempDir.newFile("test.tar")
TarArchiveOutputStream(FileOutputStream(tar)).use {
writeEntry(it, "a/b/c/rogue", link = "../f")
}
val dir = tempDir.newDirectory("unpacked")
testNoTraversal(Decompressor.Tar(tar).removePrefixPath("a/b/c"), dir, File(dir, "rogue"))
}
@Test fun prefixPathSkipsTooShortPaths() {
val tar = tempDir.newFile("test.tar")
TarArchiveOutputStream(FileOutputStream(tar)).use {