From 4b5433179e3a88f12930df7305a05688a177bcd8 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Fri, 18 Sep 2026 21:55:07 +0200 Subject: [PATCH] fix(archive): sanitize non-UTF-8 entry names during extraction (#3225) ZIP archives with GBK-encoded names inserted raw bytes into the database, failing the whole task with 'pq: invalid byte sequence for encoding UTF8'. Entry names now pass through ToValidUTF8 at both the listing and extraction layers, so masked extraction stays consistent and undecodable names degrade to replacement chars instead of a crash. The existing encoding picker (gbk/gb18030/big5/shiftjis/...) remains the way to recover proper names. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- pkg/filemanager/manager/archive.go | 4 ++-- pkg/filemanager/workflows/extract.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/filemanager/manager/archive.go b/pkg/filemanager/manager/archive.go index daded9cf..efb4ff4b 100644 --- a/pkg/filemanager/manager/archive.go +++ b/pkg/filemanager/manager/archive.go @@ -283,7 +283,7 @@ func getZipFileList(ctx context.Context, file io.ReaderAt, size int64, textEncod info := f.FileInfo() modTime := info.ModTime() fileList = append(fileList, ArchivedFile{ - Name: util.FormSlash(hdr.Name), + Name: util.FormSlash(strings.ToValidUTF8(hdr.Name, "�")), Size: info.Size(), UpdatedAt: &modTime, IsDirectory: info.IsDir(), @@ -303,7 +303,7 @@ func get7zFileList(ctx context.Context, file io.ReaderAt, size int64, extEncodin info := f.FileInfo() modTime := info.ModTime() fileList = append(fileList, ArchivedFile{ - Name: util.FormSlash(f.Name), + Name: util.FormSlash(strings.ToValidUTF8(f.Name, "�")), Size: info.Size(), UpdatedAt: &modTime, IsDirectory: info.IsDir(), diff --git a/pkg/filemanager/workflows/extract.go b/pkg/filemanager/workflows/extract.go index 9fd2dce4..3c379cdf 100644 --- a/pkg/filemanager/workflows/extract.go +++ b/pkg/filemanager/workflows/extract.go @@ -375,7 +375,7 @@ func (m *ExtractArchiveTask) masterExtractArchive(ctx context.Context, dep depen return nil } - rawPath := util.FormSlash(f.NameInArchive) + rawPath := util.FormSlash(strings.ToValidUTF8(f.NameInArchive, "�")) savePath := dst.JoinRaw(rawPath) // If file mask is not empty, check if the path is in the mask @@ -751,7 +751,7 @@ func (m *SlaveExtractArchiveTask) Do(ctx context.Context) (task.Status, error) { return nil } - rawPath := util.FormSlash(f.NameInArchive) + rawPath := util.FormSlash(strings.ToValidUTF8(f.NameInArchive, "�")) savePath := dst.JoinRaw(rawPath) // If file mask is not empty, check if the path is in the mask