首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 归档 标签 关于

最难的压缩包?

摘要

The hardest tarball? Nov 7th, 2026 Here is a curiosity: an archive that can be constructed using a single GNU tar invocation, that is extracted in 8 distinct ways depending on what tool you use. $ pri...

the tar file hard link empty and size that pax
2026-11-11 1 阅读 约5分钟阅读 thatslast
分享:
字号:
最难的压缩包? 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 ./fileempty 它从三个文件 file ./fileempty 中依次创建一个归档 Hardest.tar,其中 file 被重复,以便 GNU tar 将第二个文件存储为硬链接,empty 为空。利用第二个条目的独特路径,硬链接被重命名为咖啡馆。这会触发 tar 创建 pax 标头以将文件名存储为 UTF-8。我们将 size=512 记录添加到 pax 标头,这会覆盖硬链接中的默认 size=0。值 512 并非巧合:它恰好是 tar 标头的大小。从视觉上看,该存档具有以下结构,根据硬链接是否可以有大小有两种基本解释。现在,POSIX 表示硬链接的数据块“可能包含”在 pax 存档中,但其含义并不完全清楚。那么硬链接之后的512字节是它的数据,而不是我们归档时的空头?硬链接如何与之前的对应文件具有不同的内容?提取它 这个档案提供了迄今为止我在使用众所周知的 tar 实用程序和库提取它时遇到的最丰富和最令人惊讶的结果。以下结果是使用撰写本文时所有软件包的最新版本生成的。 GNU tar、BusyBox、Python、Go 和 Perl 这组原则上是合理的:它们忽略硬链接上的大小,并提取 file 、其硬链接咖啡馆和空。 bsdtar 这是 macOS 的系统 tar 实用程序,在硬链接大小的概念上它在精神上更接近 POSIX,并将 512 字节写入硬链接。最终结果是该文件现在包含空的 tar 标头。 7-Zip、node-tar、tar-fs 和 Rust 的 tar & astral-tokio-tar 该组同意 bsdtar 的观点,即 512 字节是硬链接的数据,但没有将它们写入硬链接。相反,它们会向前跳过数据,您只剩下 file 和咖啡馆,而没有 empty 。 Java 的 Commons 压缩 这是您开始需要更多想象力的地方。由于咖啡馆包含数据,因此会创建一个单独的文件,其中包含空的标题作为数据,而文件保留其原始内容。 PHP 的 PharData 使咖啡馆成为一个单独的空文件,并且还提取空的 .为什么不呢? RubyGems 根本不提取咖啡馆,但为了弥补这一点,它在 file 和 empty 旁边创建一个空目录 PaxHeaders 。 R R 有一种完全不同的方法:它提取包含 512 个空字节的空值。它错误地将大小应用于空而不是硬链接,并且这 512 字节来自归档结束标记。额外奖励:Haskell Haskell 的 tar 与 GNU tar 完全一样,只要它不存在字符串解码问题,将文件咖啡馆变成磁盘上的咖啡馆(在 2026 年,这不是浏览器的渲染怪癖)。 .NET、Julia 和 uv 的 tar 编解码器 这些实现拒绝 tarball。我相信这是您能做的最好的事情,即使它在技术上不符合 POSIX 标准。更多内容 这个 tarball 是我在我的测试套件 haampie/tar-minefield 中收集和分类的 134 个棘手的 tarball 之一,它是自上一篇文章以来开发的。其网站 https://stoppels.ch/tar 有一个大表格,显示实现如何处理所有这些案例,以及每个测试案例的详细信息。这篇文章的 tarball 的一个变体作为测试用例包含在内。如果您想讨论这个问题,请给我发送电子邮件:firstname[at]lastname.ch。
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱