added sup[port for more archivers
This commit is contained in:
parent
ae7cf32132
commit
0a95ad9f53
30
pom.xml
30
pom.xml
@ -21,6 +21,23 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/lib</outputDirectory>
|
||||
<includeScope>runtime</includeScope>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@ -68,4 +85,17 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.junrar</groupId>
|
||||
<artifactId>junrar</artifactId>
|
||||
<version>7.4.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -16,9 +16,17 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import com.github.junrar.Archive;
|
||||
import com.github.junrar.rarfile.FileHeader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
@ -871,22 +879,44 @@ public class FilePanelTab extends JPanel {
|
||||
private boolean isArchiveFile(File f) {
|
||||
if (f == null) return false;
|
||||
String n = f.getName().toLowerCase();
|
||||
return n.endsWith(".zip") || n.endsWith(".jar");
|
||||
return n.endsWith(".zip") || n.endsWith(".jar") || n.endsWith(".tar") || n.endsWith(".tar.gz") || n.endsWith(".tgz") || n.endsWith(".7z") || n.endsWith(".rar");
|
||||
}
|
||||
|
||||
private Path extractArchiveToTemp(File archive) {
|
||||
if (archive == null || !archive.isFile()) return null;
|
||||
String name = archive.getName().toLowerCase();
|
||||
try {
|
||||
Path tempDir = Files.createTempDirectory("kfmanager-archive-");
|
||||
|
||||
if (name.endsWith(".zip") || name.endsWith(".jar")) {
|
||||
extractZip(archive, tempDir);
|
||||
} else if (name.endsWith(".tar.gz") || name.endsWith(".tgz")) {
|
||||
extractTarGz(archive, tempDir);
|
||||
} else if (name.endsWith(".tar")) {
|
||||
extractTar(archive, tempDir);
|
||||
} else if (name.endsWith(".7z")) {
|
||||
extractSevenZ(archive, tempDir);
|
||||
} else if (name.endsWith(".rar")) {
|
||||
extractRar(archive, tempDir);
|
||||
}
|
||||
|
||||
return tempDir;
|
||||
} catch (Exception ex) {
|
||||
// extraction failed; attempt best-effort cleanup
|
||||
try {
|
||||
if (currentArchiveTempDir != null) deleteTempDirRecursively(currentArchiveTempDir);
|
||||
} catch (Exception ignore) {}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void extractZip(File archive, Path tempDir) throws IOException {
|
||||
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(archive.toPath()))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
String entryName = entry.getName();
|
||||
// Normalize entry name and prevent zip-slip
|
||||
Path resolved = tempDir.resolve(entryName).normalize();
|
||||
if (!resolved.startsWith(tempDir)) {
|
||||
// suspicious entry, skip
|
||||
zis.closeEntry();
|
||||
continue;
|
||||
}
|
||||
@ -896,20 +926,97 @@ public class FilePanelTab extends JPanel {
|
||||
} else {
|
||||
Path parent = resolved.getParent();
|
||||
if (parent != null) Files.createDirectories(parent);
|
||||
// Copy entry contents
|
||||
Files.copy(zis, resolved, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
zis.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tempDir;
|
||||
} catch (IOException ex) {
|
||||
// extraction failed; attempt best-effort cleanup
|
||||
try {
|
||||
if (currentArchiveTempDir != null) deleteTempDirRecursively(currentArchiveTempDir);
|
||||
} catch (Exception ignore) {}
|
||||
return null;
|
||||
private void extractSevenZ(File archive, Path tempDir) throws IOException {
|
||||
try (SevenZFile sevenZFile = new SevenZFile(archive)) {
|
||||
SevenZArchiveEntry entry;
|
||||
while ((entry = sevenZFile.getNextEntry()) != null) {
|
||||
String entryName = entry.getName();
|
||||
Path resolved = tempDir.resolve(entryName).normalize();
|
||||
if (!resolved.startsWith(tempDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
Files.createDirectories(resolved);
|
||||
} else {
|
||||
Path parent = resolved.getParent();
|
||||
if (parent != null) Files.createDirectories(parent);
|
||||
|
||||
try (OutputStream os = Files.newOutputStream(resolved)) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = sevenZFile.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void extractRar(File archiveFile, Path tempDir) throws Exception {
|
||||
try (Archive archive = new Archive(archiveFile)) {
|
||||
FileHeader fh = archive.nextFileHeader();
|
||||
while (fh != null) {
|
||||
String entryName = fh.getFileName().replace('\\', '/');
|
||||
Path resolved = tempDir.resolve(entryName).normalize();
|
||||
if (!resolved.startsWith(tempDir)) {
|
||||
fh = archive.nextFileHeader();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fh.isDirectory()) {
|
||||
Files.createDirectories(resolved);
|
||||
} else {
|
||||
Path parent = resolved.getParent();
|
||||
if (parent != null) Files.createDirectories(parent);
|
||||
try (OutputStream os = Files.newOutputStream(resolved)) {
|
||||
archive.extractFile(fh, os);
|
||||
}
|
||||
}
|
||||
fh = archive.nextFileHeader();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTarGz(File archive, Path tempDir) throws IOException {
|
||||
try (InputStream fis = Files.newInputStream(archive.toPath());
|
||||
InputStream gzis = new GzipCompressorInputStream(fis);
|
||||
TarArchiveInputStream tais = new TarArchiveInputStream(gzis)) {
|
||||
extractTarInternal(tais, tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTar(File archive, Path tempDir) throws IOException {
|
||||
try (InputStream fis = Files.newInputStream(archive.toPath());
|
||||
TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
|
||||
extractTarInternal(tais, tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTarInternal(TarArchiveInputStream tais, Path tempDir) throws IOException {
|
||||
TarArchiveEntry entry;
|
||||
while ((entry = tais.getNextTarEntry()) != null) {
|
||||
String entryName = entry.getName();
|
||||
Path resolved = tempDir.resolve(entryName).normalize();
|
||||
if (!resolved.startsWith(tempDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
Files.createDirectories(resolved);
|
||||
} else {
|
||||
Path parent = resolved.getParent();
|
||||
if (parent != null) Files.createDirectories(parent);
|
||||
Files.copy(tais, resolved, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user