-
Notifications
You must be signed in to change notification settings - Fork 536
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat (jkube-kit/common) : Add utility class to decompress archive fil…
…es (#2456) Add JKubeArchiveDecompressor utility class. It's extractArchive method would extract the utility class to specified folder. It only supports `.tgz` and `.zip` files at the moment. Signed-off-by: Rohan Kumar <[email protected]>
- Loading branch information
1 parent
031d08f
commit 659ff96
Showing
7 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
...t/common/src/main/java/org/eclipse/jkube/kit/common/archive/JKubeArchiveDecompressor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.common.archive; | ||
|
||
import org.apache.commons.compress.archivers.ArchiveEntry; | ||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; | ||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; | ||
import org.eclipse.jkube.kit.common.util.FileUtil; | ||
|
||
import java.io.BufferedInputStream; | ||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.zip.ZipEntry; | ||
import java.util.zip.ZipInputStream; | ||
|
||
public class JKubeArchiveDecompressor { | ||
private JKubeArchiveDecompressor() { } | ||
|
||
/** | ||
* Extracts a given archive file to specified target directory | ||
* | ||
* @param inputArchiveFile input archive file | ||
* @param targetDirectory target folder where you want to extract | ||
* @throws IOException in case of failure while trying to create any directory | ||
*/ | ||
public static void extractArchive(File inputArchiveFile, File targetDirectory) throws IOException { | ||
if (targetDirectory.exists()) { | ||
FileUtil.cleanDirectory(targetDirectory); | ||
} | ||
Files.createDirectory(targetDirectory.toPath()); | ||
if (inputArchiveFile.getName().endsWith(".tgz")) { | ||
extractTarArchive(inputArchiveFile, targetDirectory.toPath()); | ||
} else if (inputArchiveFile.getName().endsWith(".zip")) { | ||
extractZipArchive(inputArchiveFile, targetDirectory.toPath()); | ||
} | ||
} | ||
|
||
private static void extractTarArchive(File downloadedArchive, Path targetExtractionDir) throws IOException { | ||
try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(downloadedArchive.toPath())); | ||
TarArchiveInputStream tar = new TarArchiveInputStream(new GzipCompressorInputStream(inputStream))) { | ||
ArchiveEntry entry; | ||
while ((entry = tar.getNextEntry()) != null) { | ||
Path extractTo = targetExtractionDir.resolve(entry.getName()); | ||
if (entry.isDirectory()) { | ||
Files.createDirectories(extractTo); | ||
} else { | ||
Files.copy(tar, extractTo); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static void extractZipArchive(File downloadedArchive, Path targetExtractionDir) throws IOException { | ||
byte[] buffer = new byte[1024]; | ||
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(downloadedArchive.toPath()))) { | ||
ZipEntry zipEntry = zis.getNextEntry(); | ||
while (zipEntry != null) { | ||
File newFile = new File(targetExtractionDir.toFile(), zipEntry.getName()); | ||
if (zipEntry.isDirectory()) { | ||
if (!newFile.isDirectory() && !newFile.mkdirs()) { | ||
Check failure Code scanning / SonarCloud Extracting archives should not lead to zip slip vulnerabilities Critical
Change this code to not construct the path from file name entry of an archive. See more on SonarCloud
|
||
throw new IOException("Failed to create directory " + newFile); | ||
} | ||
} else { | ||
try (FileOutputStream fos = new FileOutputStream(newFile)) { | ||
Check failure Code scanning / SonarCloud Extracting archives should not lead to zip slip vulnerabilities Critical
Change this code to not construct the path from file name entry of an archive. See more on SonarCloud
|
||
int len; | ||
while ((len = zis.read(buffer)) > 0) { | ||
fos.write(buffer, 0, len); | ||
} | ||
} | ||
} | ||
zipEntry = zis.getNextEntry(); | ||
} | ||
zis.closeEntry(); | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
...mmon/src/test/java/org/eclipse/jkube/kit/common/archive/JKubeArchiveDecompressorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.common.archive; | ||
|
||
import org.eclipse.jkube.kit.common.assertj.FileAssertions; | ||
import org.junit.jupiter.api.io.TempDir; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.CsvSource; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
|
||
class JKubeArchiveDecompressorTest { | ||
@TempDir | ||
private File temporaryFolder; | ||
|
||
@ParameterizedTest | ||
@CsvSource({ | ||
"/archives/pack-v0.31.0-linux.tgz,pack", | ||
"/archives/pack-v0.31.0-windows.zip,pack.exe" | ||
}) | ||
void extractArchive_whenArchiveWithSingleFileProvided_thenExtractToSpecifiedDir(String filePath, String expectedFileInExtractedArchiveName) throws IOException { | ||
// Given | ||
File input = new File(getClass().getResource(filePath).getFile()); | ||
|
||
// When | ||
JKubeArchiveDecompressor.extractArchive(input, temporaryFolder); | ||
|
||
// Then | ||
FileAssertions.assertThat(temporaryFolder) | ||
.exists() | ||
.fileTree() | ||
.containsExactlyInAnyOrder(expectedFileInExtractedArchiveName); | ||
} | ||
|
||
@ParameterizedTest | ||
@CsvSource({ | ||
"/archives/nested-archive.tgz,nested,nested/folder,nested/folder/artifact", | ||
"/archives/nested-archive.zip,nested,nested/folder,nested/folder/artifact.exe" | ||
}) | ||
void extractArchive_whenArchiveWithNestedDir_thenExtractToSpecifiedDir(String filePath, String parentDir, String artifactParentDir, String artifact) throws IOException { | ||
// Given | ||
File input = new File(getClass().getResource(filePath).getFile()); | ||
|
||
// When | ||
JKubeArchiveDecompressor.extractArchive(input, temporaryFolder); | ||
|
||
// Then | ||
FileAssertions.assertThat(temporaryFolder) | ||
.exists() | ||
.fileTree() | ||
.containsExactlyInAnyOrder(parentDir, artifactParentDir, artifact); | ||
} | ||
} |
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+112 Bytes
jkube-kit/common/src/test/resources/archives/pack-v0.31.0-linux.tgz
Binary file not shown.
Binary file added
BIN
+166 Bytes
jkube-kit/common/src/test/resources/archives/pack-v0.31.0-windows.zip
Binary file not shown.