跳到正文
认知
返回认知精选
认知精选科技大约 9 小时前2
单一来源当前只有一个可用来源,尚未完成多源交叉核验

最难的压缩包?

最难的 tarball?

2026年11月7日

这是一个有趣的现象:一个可以通过单次 GNU tar 调用构建的归档文件,但根据你使用的工具不同,它有 8 种截然不同的解压方式。

$ printf hello > file $ touch empty $ tar --format=pax --pax-option='delete=?time,size:=512' \ --transform='s,^\./file$,café,' \ -cf hardest.tar file ./file empty

它按顺序从三个文件 file ./file empty 创建了归档文件 hardest.tar,其中 file 被重复,以便 GNU tar 将第二个作为硬链接存储,而 empty 是空的。

利用第二个条目的唯一路径,硬链接被重命名为 café。这触发了 tar 创建一个 pax 头部,以 UTF-8 存储文件名。我们在 pax 头部添加了一个 size=512 记录,这覆盖了硬链接的默认 size=0。数值 512 并非巧合:它恰好是一个 tar 头部的大小。

从视觉上看,这个归档具有以下结构,基于硬链接是否可以拥有大小,有两种基本解释。

现在,POSIX 规定硬链接的数据块“可以包含”在 pax 归档中,但这其中的含义并不完全清楚。那么,硬链接之后的 512 字节是它的数据,而不是我们归档时的 empty 的头部?硬链接怎么能与其前一个对应文件 file 拥有不同的内容?

解压它

使用知名的 tar 工具和库解压这个归档时,我迄今为止遇到的结果最丰富、也最令人惊讶。下面的结果是在撰写本文时,使用所有软件包的最新版本生成的。

GNU tar, BusyBox, Python, Go 和 Perl

这一组在原则上讲得通:它们忽略了硬链接上的大小,并解压出 file、它的硬链接 café 和 empty。

bsdtar

这是 macOS 的系统 tar 工具,在硬链接大小这一概念上,它在精神上更接近 POSIX,并将 512 字节写入硬链接。最终结果是 file 现在包含了 empty 的 tar 头部。

7-Zip, node-tar, tar-fs 和 Rust 的 tar & astral-tokio-tar

这一组同意 bsdtar 的观点,即 512 字节是硬链接的数据,但并没有将它们写入硬链接。相反,它们跳过这些数据,结果只剩下 file 和 café,没有 empty。

Java 的 Commons Compress

这就需要你发挥更多想象力了。因为 café 包含数据,所以创建了一个单独的文件,其中包含 empty 的头部作为数据,而 file 保持其原始内容。

PHP 的 PharData

让 café 成为单独的空文件,同时也解压出 empty。为什么不呢?

RubyGems

根本不解压 café,但为了弥补这一点,它在 file 和 empty 旁边创建了一个空目录 PaxHeaders。

R 采用了完全不同的方法:它解压出 empty,其中包含 512 个空字节。它错误地将大小应用到了 empty 而不是硬链接上,而这 512 字节来自一个归档结束标记。

附赠:Haskell

Haskell 的 tar 程序如果不存在字符串解码问题,就会和 GNU tar 完全一样,否则它会把文件 café 变成 café 存储在磁盘上(在 2026 年,这并不是你浏览器的渲染怪癖)。

.NET、Julia 和 uv 的 tar-codec

这些实现会拒绝这个 tarball。我相信这是你能做的最好的事情,即使这在技术上不符合 POSIX 标准。

More of this

这个 tarball 是我正在我的测试套件 haampie/tar-minefield 中收集和分类的 134 个棘手 tarball 之一,该测试套件自上一篇文章以来一直在开发。

其网站 https://stoppels.ch/tar 有一个巨大的表格,展示了实现如何处理所有这些情况,以及每个测试用例的详细信息。本文的 tarball 的一个变体被包含为一个测试用例。

如果你想讨论这个问题,请给我发送电子邮件至 firstname[at]lastname.ch。

Evidence

来源与证据

单一来源 · 1 个信源

当前仅有一个可用来源,尚未完成多源交叉核验。

发布时间
内容处理
AI 翻译 / 摘要,需结合原文核对
内容有误或来源失效?告诉我们

每天早上收到这 5 条

免注册,填邮箱即可;每封邮件都能一键退订。

提交即表示同意按隐私说明保存你的邮箱,只用于发送简报。

或用 RSS 订阅

AI 翻译、摘要和解读仅用于辅助判断;涉及重要决策时,请回到上方来源核实。