mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 15:10:01 +08:00
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
70 lines
1.2 KiB
Go
70 lines
1.2 KiB
Go
package zipx
|
|
|
|
import (
|
|
"archive/zip"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
|
)
|
|
|
|
func Unpacking(name, destPath string, mapper func(f *zip.File) bool) error {
|
|
r, err := zip.OpenReader(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer r.Close()
|
|
|
|
destAbsPath, err := filepath.Abs(destPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, file := range r.File {
|
|
ok := mapper(file)
|
|
if ok {
|
|
err = fileCopy(file, destAbsPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func fileCopy(file *zip.File, destPath string) error {
|
|
rc, err := file.Open()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rc.Close()
|
|
|
|
// Ensure the file path does not contain directory traversal elements
|
|
if strings.Contains(file.Name, "..") {
|
|
return fmt.Errorf("invalid file path: %s", file.Name)
|
|
}
|
|
|
|
abs, err := filepath.Abs(file.Name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filename := filepath.Join(destPath, filepath.Base(abs))
|
|
dir := filepath.Dir(filename)
|
|
err = pathx.MkdirIfNotExist(dir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
w, err := os.Create(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer w.Close()
|
|
_, err = io.Copy(w, rc)
|
|
return err
|
|
}
|