fix: Fix file decompression issue (#10320)

This commit is contained in:
2025-09-09 19:14:44 +08:00 committed by GitHub
parent c8f19467ba
commit ee33fdab89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 70 additions and 19 deletions

View file

@ -3,6 +3,7 @@ package files
import (
"archive/zip"
"bufio"
"compress/gzip"
"context"
"crypto/tls"
"encoding/json"
@ -597,10 +598,10 @@ func getFormat(cType CompressType) archiver.CompressedArchive {
format.Archival = archiver.Zip{
Compression: zip.Deflate,
}
case Bz2:
case Bz2, TarBz2:
format.Compression = archiver.Bz2{}
format.Archival = archiver.Tar{}
case Xz:
case Xz, TarXz:
format.Compression = archiver.Xz{}
format.Archival = archiver.Tar{}
}
@ -680,6 +681,13 @@ func decodeGBK(input string) (string, error) {
func (f FileOp) decompressWithSDK(srcFile string, dst string, cType CompressType) error {
format := getFormat(cType)
if cType == Gz {
err := f.DecompressGzFile(srcFile, dst)
if err != nil {
return err
}
}
handler := func(ctx context.Context, archFile archiver.File) error {
info := archFile.FileInfo
if isIgnoreFile(archFile.Name()) {
@ -794,6 +802,41 @@ func ZipFile(files []archiver.File, dst afero.File) error {
return nil
}
func (f FileOp) DecompressGzFile(srcFile, dst string) error {
in, err := f.Fs.Open(srcFile)
if err != nil {
return fmt.Errorf("open source file failed: %w", err)
}
defer in.Close()
gr, err := gzip.NewReader(in)
if err != nil {
return fmt.Errorf("gzip reader creation failed: %w", err)
}
defer gr.Close()
outName := strings.TrimSuffix(filepath.Base(srcFile), ".gz")
outPath := filepath.Join(dst, outName)
parentDir := filepath.Dir(outPath)
if !f.Stat(parentDir) {
if err := f.Fs.MkdirAll(parentDir, 0755); err != nil {
return err
}
}
fw, err := f.Fs.OpenFile(outPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return fmt.Errorf("create output file failed: %w", err)
}
defer fw.Close()
if _, err := io.Copy(fw, gr); err != nil {
return fmt.Errorf("copy content failed: %w", err)
}
return nil
}
func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules string) error {
if !f.Stat(path.Dir(dst)) {
if err := f.Fs.MkdirAll(path.Dir(dst), constant.FilePerm); err != nil {

View file

@ -460,9 +460,11 @@ const (
Zip CompressType = "zip"
Gz CompressType = "gz"
Bz2 CompressType = "bz2"
TarBz2 CompressType = "tar.bz2"
Tar CompressType = "tar"
TarGz CompressType = "tar.gz"
Xz CompressType = "xz"
TarXz CompressType = "tar.xz"
SdkZip CompressType = "sdkZip"
SdkTarGz CompressType = "sdkTarGz"
Rar CompressType = "rar"

View file

@ -2,6 +2,7 @@ package files
import (
"fmt"
"os"
"path/filepath"
"strings"
@ -17,6 +18,9 @@ func NewTarGzArchiver() ShellArchiver {
}
func (t TarGzArchiver) Extract(filePath, dstDir string, secret string) error {
if err := os.MkdirAll(dstDir, 0755); err != nil {
return fmt.Errorf("failed to create destination dir: %w", err)
}
var err error
commands := ""
if len(secret) != 0 {

View file

@ -2,10 +2,12 @@ export enum CompressType {
Zip = 'zip',
Gz = 'gz',
Bz2 = 'bz2',
TarBz2 = 'tar.bz2',
Tar = 'tar',
TGz = 'tgz',
TarGz = 'tar.gz',
Xz = 'xz',
TarXz = 'tar.xz',
Rar = 'rar',
'7z' = '7z',
}
@ -13,11 +15,13 @@ export enum CompressType {
export enum CompressExtension {
zip = '.zip',
gz = '.gz',
bz2 = '.tar.bz2',
'tar.bz2' = '.tar.bz2',
bz2 = '.bz2',
tar = '.tar',
tgz = '.tgz',
'tar.gz' = '.tar.gz',
xz = '.tar.xz',
'tar.xz' = '.tar.xz',
xz = '.xz',
rar = '.rar',
'7z' = '.7z',
}

View file

@ -18,6 +18,7 @@ export const Mimetypes = new Map([
['application/octet-stream', CompressType.Tar],
['application/x-rar-compressed', CompressType.Rar],
['application/vnd.rar', CompressType.Rar],
['application/rar', CompressType.Rar],
['application/x-7z-compressed', CompressType['7z']],
]);

View file

@ -39,7 +39,6 @@ import { File } from '@/api/interface/file';
import { FormInstance, FormRules } from 'element-plus';
import { Rules } from '@/global/form-rules';
import { deCompressFile } from '@/api/modules/files';
import { Mimetypes } from '@/global/mimetype';
import FileList from '@/components/file-list/index.vue';
import { MsgSuccess } from '@/utils/message';
@ -48,7 +47,7 @@ interface CompressProps {
dst: string;
name: string;
path: string;
mimeType: string;
type: string;
}
const rules = reactive<FormRules>({
@ -72,14 +71,6 @@ const handleClose = () => {
em('close', open);
};
const getFileType = (mime: string): string => {
if (Mimetypes.get(mime) != undefined) {
return String(Mimetypes.get(mime));
} else {
return '';
}
};
const getLinkPath = (path: string) => {
form.value.dst = path;
};
@ -103,7 +94,7 @@ const submit = async (formEl: FormInstance | undefined) => {
};
const acceptParams = (props: CompressProps) => {
form.value.type = getFileType(props.mimeType);
form.value.type = props.type;
form.value.dst = props.dst;
form.value.path = props.path;
name.value = props.name;

View file

@ -688,7 +688,7 @@ import VscodeOpenDialog from '@/components/vscode-open/index.vue';
import { debounce } from 'lodash-es';
import TerminalDialog from './terminal/index.vue';
import { Dashboard } from '@/api/interface/dashboard';
import { CompressExtension, MimetypeByExtensionObject } from '@/enums/files';
import { CompressExtension } from '@/enums/files';
import type { TabPaneName } from 'element-plus';
const globalStore = GlobalStore();
@ -733,7 +733,7 @@ let pointer = -1;
const fileCreate = reactive({ path: '/', isDir: false, mode: 0o755 });
const fileCompress = reactive({ files: [''], name: '', dst: '', operate: 'compress' });
const fileDeCompress = reactive({ path: '', name: '', dst: '', mimeType: '' });
const fileDeCompress = reactive({ path: '', name: '', dst: '', type: '' });
const fileEdit = reactive({ content: '', path: '', name: '', language: 'plaintext', extension: '' });
const filePreview = reactive({ path: '', name: '', extension: '', fileType: '', imageFiles: [], currentNode: '' });
const codeReq = reactive({ path: '', expand: false, page: 1, pageSize: 100, isDetail: false });
@ -1186,9 +1186,9 @@ const openDeCompress = (item: File.File) => {
MsgWarning(i18n.global.t('file.canNotDeCompress'));
return;
}
fileDeCompress.mimeType = item.mimeType;
fileDeCompress.type = Mimetypes.get(item.mimeType);
if (CompressExtension[Mimetypes.get(item.mimeType)] != item.extension) {
fileDeCompress.mimeType = MimetypeByExtensionObject[item.extension];
fileDeCompress.type = getEnumKeyByValue(item.extension);
}
fileDeCompress.name = item.name;
@ -1198,6 +1198,12 @@ const openDeCompress = (item: File.File) => {
deCompressRef.value.acceptParams(fileDeCompress);
};
function getEnumKeyByValue(value: string): keyof typeof CompressExtension | undefined {
return (Object.keys(CompressExtension) as Array<keyof typeof CompressExtension>).find(
(k) => CompressExtension[k] === value,
);
}
const openView = (item: File.File) => {
const fileType = getFileType(item.extension);
if (fileType === 'image') {