Decompressor - flip cut dirs and filter, add more tests

GitOrigin-RevId: 437231f0e937bbdc79285246a5429110dc047173
This commit is contained in:
Eugene Petrenko
2019-11-07 02:40:58 +00:00
committed by intellij-monorepo-bot
parent 2e3a0e85eb
commit f581a02207
2 changed files with 32 additions and 15 deletions
@@ -19,8 +19,6 @@ import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.List;
import java.util.StringJoiner;
import java.util.function.Function;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -156,7 +154,9 @@ public abstract class Decompressor {
/**
* Removes several leading directories from the archive during extraction.
* Some entries may clash, so use {@link #overwrite(boolean)} to control it.
* Some short file entries may be lost
* Some short file entries may be lost.
*
* Executed AFTER filter test!
*
* @param dirsToCut how many directories has to be removed from archive entry names
* @return self
@@ -172,19 +172,17 @@ public abstract class Decompressor {
try {
Entry entry;
while ((entry = nextEntry()) != null) {
entry = entry.cutDirs(myCutDirs);
if (entry == null) continue;
String name = entry.name;
if (myFilter != null) {
String entryName = entry.type == Type.DIR && !StringUtil.endsWithChar(name, '/') ? name + '/' : name;
String entryName = entry.type == Type.DIR && !StringUtil.endsWithChar(entry.name, '/') ? entry.name + '/' : entry.name;
if (!myFilter.value(entryName)) {
continue;
}
}
File outputFile = entryFile(outputDir, name);
entry = entry.cutDirs(myCutDirs);
if (entry == null) continue;
File outputFile = entryFile(outputDir, entry.name);
switch (entry.type) {
case DIR:
@@ -215,7 +213,7 @@ public abstract class Decompressor {
case SYMLINK:
if (StringUtil.isEmpty(entry.linkTarget) ||
!FileUtil.isAncestor(outputDir, new File(FileUtil.toCanonicalPath(outputFile.getParent() + '/' + entry.linkTarget)), true)) {
throw new IOException("Invalid symlink entry: " + name + " -> " + entry.linkTarget);
throw new IOException("Invalid symlink entry: " + entry.name + " -> " + entry.linkTarget);
}
FileUtil.createParentDirs(outputFile);
Files.createSymbolicLink(outputFile.toPath(), Paths.get(entry.linkTarget));
@@ -142,7 +142,7 @@ class DecompressorTest {
testNoTraversal(Decompressor.Tar(tar).withSymlinks(), dir, File(dir, "rogue"))
}
@Test fun mapsFilesInZip() {
@Test fun cutDirsFilesInZip() {
val zip = tempDir.newFile("test.zip")
ZipOutputStream(FileOutputStream(zip)).use { writeEntry(it, "a/b/c.txt") }
val dir = tempDir.newFolder("unpacked")
@@ -154,7 +154,26 @@ class DecompressorTest {
assertThat(File(dir, "b")).doesNotExist()
}
@Test fun mapsFilesInTarWithSymlinks() {
@Test fun cutDirsFilesInZipWitFilter() {
val zip = tempDir.newFile("test.zip")
ZipOutputStream(FileOutputStream(zip)).use {
writeEntry(it, "a/b/c.txt")
writeEntry(it, "skip.txt")
}
val dir = tempDir.newFolder("unpacked")
val filterLog = mutableListOf<String>()
Decompressor.Zip(zip).cutDirs(2).filter { filterLog.add(it) }.extract(dir)
assertThat(File(dir, "c.txt")).isFile()
assertThat(File(dir, "a")).doesNotExist()
assertThat(File(dir, "a/b")).doesNotExist()
assertThat(File(dir, "b")).doesNotExist()
//it must call filter before cut-dirs
Assert.assertEquals(setOf("a/b/c.txt", "skip.txt"), filterLog.toSet())
}
@Test fun cutDirsFilesInTarWithSymlinks() {
assumeSymLinkCreationIsSupported()
val tar = tempDir.newFile("test.tar")
@@ -169,7 +188,7 @@ class DecompressorTest {
assertThat(File(dir, "links/ok").toPath()).isSymbolicLink().hasSameContentAs(File(dir, "f").toPath())
}
@Test fun mapRogueSymlinks() {
@Test fun cutDirRogueSymlinks() {
assumeSymLinkCreationIsSupported()
val tar = tempDir.newFile("test.tar")
@@ -178,7 +197,7 @@ class DecompressorTest {
testNoTraversal(Decompressor.Tar(tar).cutDirs(3), dir, File(dir, "rogue"))
}
@Test fun mapSkipsTooShortPaths() {
@Test fun cutDirSkipsTooShortPaths() {
assumeSymLinkCreationIsSupported()
val tar = tempDir.newFile("test.tar")