golang的archive/zip
包提供了解压zip文件的功能,但生产环境需要做一些校验以免服务被攻击。因此我封装了一个解压zip的方法,校验条件包含:最大解压文件/文件夹数,解压限时,解压出来文件大小之和,解压的根目录。
代码如下:
package main
import (
"fmt"
"time"
"os"
"io"
"archive/zip"
"path/filepath"
)
func main(){
fmt.Println(Unzip("test.zip","./unzip/",60*2,500,1024*1024*10))
}
func Unzip(
zipfile string, // zip文件路径
outbasedir string, // 解压的根文件夹
maxtime\_seconds int64, // 最多解压用时
maxfiles int64, // 最大允许多少个文件
maxSizeOfExtraFileAll uint64, // 解压之后的文件字节之和
) bool {
e := os.MkdirAll(outbasedir, 0644)
if e!=nil{return false}
begin := time.Now().UnixNano()
sizeOfAll := uint64(0)
fi, e := zip.OpenReader(zipfile)
if e!=nil {return false}
defer fi.Close()
for _, v := range fi.File {
maxfiles--
if maxfiles<=0{return false}
if (time.Now().UnixNano()-begin)/1e9 > maxtime_seconds{return false}
info := v.FileInfo()
fn,e := filepath.Abs(outbasedir+"/"+v.Name)
sizeOfAll += v.UncompressedSize64
if sizeOfAll>maxSizeOfExtraFileAll{return false}
if e!=nil{continue}
if info.IsDir() {
e := os.MkdirAll(fn, 0644)
if e!=nil{continue}
}
srcFile,e := v.Open()
if e!=nil{continue}
defer srcFile.Close()
newFile,e := os.Create(fn)
if e!=nil{continue}
io.Copy(newFile, srcFile)
newFile.Close()
}
return true
}
相关文档
暂无
随便看看
畅言模块加载中