Golang解压zip文件到指定目录方法
作者:SunnyJourney
时间:2026-04-14
浏览:0
使用archive/zip解压zip文件前必须检查io.ErrUnexpectedEOF,严格过滤路径遍历(如../),手动处理GBK中文文件名编码,并区分处理symlink等特殊文件类型,否则易致安全漏洞或静默失败。
使用 archive/zip 解压 zip 文件前必须检查 io.ErrUnexpectedEOF,严格过滤路径遍历(如 ../),手动处理 GBK 中文文件名编码,并区分处理 symlink 等特殊文件类型,否则易致安全漏洞或静默失败。

用 archive/zip 打开 zip 文件前必须检查 io.ErrUnexpectedEOF
直接 zip.OpenReader 读损坏或不完整的 zip 包会 panic 或静默失败,常见错误是 zip: not a valid zip file 或更隐蔽的 unexpected EOF。这不是代码写错了,而是 zip 流没读完就被关闭了。
实操建议:
- 先用
os.Stat确认文件存在且大小 > 0 - 打开后立即 defer
zipReader.Close(),但别在 defer 里忽略错误 ——Close()可能返回io.ErrUnexpectedEOF,说明解压中途出问题 - 如果从网络或 io.Reader 流式读取,务必用
io.LimitReader或完整缓存再解析,archive/zip不支持边读边解
解压时路径遍历漏洞(../../../etc/passwd)必须手动过滤
Go 标准库 archive/zip 不做路径安全校验。攻击者构造含 ../ 的文件名,filepath.Join(dst, f.Name) 会直接写到任意目录,这是线上高危风险。
实操建议:
- 对每个
zip.File.Header.Name调用strings.HasPrefix(f.Name, "..") || strings.Contains(f.Name, "../")判断 - 更稳妥的是用
filepath.Clean(f.Name)后比对是否仍以".."开头,或是否包含filepath.Separator之外的非法路径分隔符(如 Windows 下的\) - 不要依赖
filepath.Abs()—— 它在某些情况下会绕过校验
os.ModeSymlink 和 os.ModeDevice 权限位在解压时会被忽略
zip 文件里可以存 symlink、device node 等特殊文件,但 Go 的 os.WriteFile 和 ioutil.WriteFile(已弃用)无法还原这些类型。直接写入会导致权限位丢失,甚至创建空文件。
实操建议:
- 检查
f.IsDir()和f.Mode() & os.ModeSymlink != 0,对 symlink 单独用os.Symlink(f.Name, dstPath) - 跳过
os.ModeDevice、os.ModeNamedPipe等非普通文件(除非你明确需要支持) - 目录必须提前
os.MkdirAll,且传入f.Mode()—— 注意 zip 中目录权限常为0o40755,不是0o755
中文文件名乱码:Windows 打包的 zip 默认用 GBK,Go 默认按 UTF-8 解析
Windows 上用资源管理器或旧版压缩软件打的 zip,文件名编码是 GBK(或 GB18030),但 archive/zip 总按 UTF-8 解码 Header.Name,结果就是一堆 .txt。
实操建议:
- 优先让上游改用 UTF-8 编码打包(7-Zip / zip -U / macOS 默认都支持)
- 若必须兼容,用
golang.org/x/text/encoding/simplifiedchinese手动 decode:decoder := simplifiedchinese.GBK.NewDecoder() name, _ = decoder.String(f.Name)
- 注意:只对
f.Name和f.Comment做,别碰f.Extra或内容流
作者最新文章
图几
2026-09-16 17:43
SQL中ROUND函数对0.5的处理机制及强制四舍五入方法
2026-09-15 14:19
JS金额计算怎么避免四舍五入误差
2026-09-14 17:32
韩国8月携号转网数据:Galaxy Z8系列iPhone用户转化率约为Z7系列2倍
2026-09-08 17:02
AE基础教程:如何创建合成并制作关键帧动画
2026-09-04 09:27
上一篇:
圆通快递单号查询官网入口
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多


































