Skip to content

Instantly share code, notes, and snippets.

@virusdefender
Created April 14, 2020 10:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save virusdefender/f8c127ab420942dd99acbf269aca9cc7 to your computer and use it in GitHub Desktop.
Save virusdefender/f8c127ab420942dd99acbf269aca9cc7 to your computer and use it in GitHub Desktop.
dangerous unzip
package main
import (
"archive/zip"
"fmt"
"io"
"log"
"os"
"path/filepath"
)
// copy from https://stackoverflow.com/a/24792688/2737403
func Unzip(src, dest string) error {
r, err := zip.OpenReader(src)
if err != nil {
return err
}
defer func() {
if err := r.Close(); err != nil {
panic(err)
}
}()
os.MkdirAll(dest, 0755)
// Closure to address file descriptors issue with all the deferred .Close() methods
extractAndWriteFile := func(f *zip.File) error {
rc, err := f.Open()
if err != nil {
return err
}
defer func() {
if err := rc.Close(); err != nil {
panic(err)
}
}()
path := filepath.Join(dest, f.Name)
fmt.Println(f.Name)
if f.FileInfo().IsDir() {
os.MkdirAll(path, f.Mode())
} else {
os.MkdirAll(filepath.Dir(path), f.Mode())
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
defer func() {
if err := f.Close(); err != nil {
panic(err)
}
}()
_, err = io.Copy(f, rc)
if err != nil {
return err
}
}
return nil
}
for _, f := range r.File {
err := extractAndWriteFile(f)
if err != nil {
return err
}
}
return nil
}
func main() {
// copy from https://golang.org/pkg/archive/zip/#example_Writer
// Create a buffer to write our archive to.
f, err := os.Create("/tmp/test.zip")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Create a new zip archive.
w := zip.NewWriter(f)
// Add some files to the archive.
var files = []struct {
Name, Body string
}{
{"../../test.txt", "i am test"},
{"../foo.txt", "i am foo"},
{"bar.txt", "i am bar"},
}
for _, file := range files {
f, err := w.Create(file.Name)
if err != nil {
log.Fatal(err)
}
_, err = f.Write([]byte(file.Body))
if err != nil {
log.Fatal(err)
}
}
// Make sure to check the error on Close.
err = w.Close()
if err != nil {
log.Fatal(err)
}
err = Unzip("/tmp/test.zip", "/tmp/dir1/dir2")
if err != nil {
log.Fatal(err)
}
}
@virusdefender
Copy link
Author

/tmp/dir1
├── dir2
│   └── bar.txt
└── foo.txt

1 directory, 2 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment