最难解的 tar 包:一个归档,八种解包结果
来源:stoppels.ch — 2026-11-07
📋 概述
作者用一条 GNU tar 命令造出一个畸形归档:把 file 重复归档以产生硬链接,再用 UTF-8 文件名逼 tar 生成 pax 头,然后手工注入 size=512——恰好是一个 tar 头的长度。于是硬链接后面那 512 字节到底是数据还是下一个文件的头,成了悬案,而 POSIX 只含糊地说硬链接的数据库「可以包含」。结果 GNU tar、BusyBox、Python、Go、Perl 走一组,bsdtar 一组,7-Zip/node-tar/Rust 一组,Java Commons Compress、PHP PharData、RubyGems、R 各走一路,.NET、Julia 直接拒收。
🔑 核心要点
- 关键技巧是 pax 头的 size:=512:512 正好等于一个 tar 头长度,于是「数据」和「头部」无法区分
- bsdtar(macOS 自带的 tar)把 512 字节写进硬链接,file 的内容变成了 empty 的头
- 7-Zip、node-tar、tar-fs 与 Rust 的 tar 跳过这 512 字节,结果少解出一个 empty
- Java Commons Compress 多造一个文件装 empty 的头,RubyGems 不解 café 而是凭空建了个 PaxHeaders 目录
- R 把 size 错挂到 empty 上写出 512 个空字节;.NET、Julia、uv 直接拒收,作者认为拒收才是最优解
💡 金句
这些实现里,拒收这个 tar 包我认为是最好的做法,哪怕严格说并不符合 POSIX。
👍 0
👎 0
← 返回 Lobsters 首页