mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[platform] lifting Decompressor's symlink target scope checks
... because inconvenient and incomplete GitOrigin-RevId: 4de4c0c6ee1abaf962e89c9dafdc88e62855f606
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f5425ef66f
commit
a3e127d72d
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user