2018-12-09 16:49:27 +13:00
|
|
|
package archive
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/zip"
|
2021-05-24 17:27:07 +12:00
|
|
|
"fmt"
|
2018-12-09 16:49:27 +13:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2021-05-24 17:27:07 +12:00
|
|
|
"strings"
|
2022-10-17 15:29:12 -03:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2018-12-09 16:49:27 +13:00
|
|
|
)
|
|
|
|
|
2021-05-24 17:27:07 +12:00
|
|
|
// UnzipFile will decompress a zip archive, moving all files and folders
|
|
|
|
// within the zip file (parameter 1) to an output directory (parameter 2).
|
|
|
|
func UnzipFile(src string, dest string) error {
|
|
|
|
r, err := zip.OpenReader(src)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer r.Close()
|
|
|
|
|
|
|
|
for _, f := range r.File {
|
|
|
|
p := filepath.Join(dest, f.Name)
|
|
|
|
|
|
|
|
// Check for ZipSlip. More Info: http://bit.ly/2MsjAWE
|
|
|
|
if !strings.HasPrefix(p, filepath.Clean(dest)+string(os.PathSeparator)) {
|
|
|
|
return fmt.Errorf("%s: illegal file path", p)
|
|
|
|
}
|
|
|
|
|
|
|
|
if f.FileInfo().IsDir() {
|
|
|
|
// Make Folder
|
|
|
|
os.MkdirAll(p, os.ModePerm)
|
2025-04-22 18:09:36 -03:00
|
|
|
|
2021-05-24 17:27:07 +12:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2025-04-22 18:09:36 -03:00
|
|
|
if err := unzipFile(f, p); err != nil {
|
2021-05-24 17:27:07 +12:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func unzipFile(f *zip.File, p string) error {
|
|
|
|
// Make File
|
|
|
|
if err := os.MkdirAll(filepath.Dir(p), os.ModePerm); err != nil {
|
|
|
|
return errors.Wrapf(err, "unzipFile: can't make a path %s", p)
|
|
|
|
}
|
2025-04-22 18:09:36 -03:00
|
|
|
|
2021-05-24 17:27:07 +12:00
|
|
|
outFile, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "unzipFile: can't create file %s", p)
|
|
|
|
}
|
|
|
|
defer outFile.Close()
|
2025-04-22 18:09:36 -03:00
|
|
|
|
2021-05-24 17:27:07 +12:00
|
|
|
rc, err := f.Open()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "unzipFile: can't open zip file %s in the archive", f.Name)
|
|
|
|
}
|
|
|
|
defer rc.Close()
|
|
|
|
|
2025-04-22 18:09:36 -03:00
|
|
|
if _, err = io.Copy(outFile, rc); err != nil {
|
2021-05-24 17:27:07 +12:00
|
|
|
return errors.Wrapf(err, "unzipFile: can't copy an archived file content")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|