1つのtarballが8通りの解釈を生む、tarの地雷原
The Hardest Tarball?
GNU tarの1回の実行で作れる巧妙なtarballが、展開するツールによって8通りもの異なる結果を生む。ハードリンクにsize=512を上書きするpaxヘッダーを仕込み、tarヘッダーのサイズを悪用したものだ。bsdtarはハードリンクにヘッダーを書き込み、7-ZipやRustのtarはデータを読み飛ばし、RubyGemsは謎のPaxHeadersディレクトリを作る。著者はこうした134個のtarballを集めたテストスイートtar-minefieldを公開している。
私は、たとえ技術的にPOSIX準拠でなくても、こうしたtarballを拒否するのが最善だと考えている。
HNでの議論
31- Joker_vD
> さて、POSIXではハードリンクのデータブロックはpaxアーカイブに「含めてもよい」とされていますが、その意味するところは完全には明らかではありません。
どうしてですか?データブロックが含まれているなら、それはそのハードリンクの背後にあるファイルの意図された内容です。それらはファイルの以前の内容を上書きするべきです。
> つまり、ハードリンクの後の512バイトはそのデータであり、我々がアーカイブした空のヘッダーではないのですか?
はい、まさにその通りです。
> どうしてハードリンクが以前の対応するファイルと異なる内容を持ち得るのでしょうか?
なぜなら、とても簡単です:アーカイブが作成されている間に、2つの異なるハードリンクの背後にあるファイルが変更されたのです。アーカイブユーティリティはそれに気づき、元のファイルを巻き戻してアーカイブ内で上書きする代わりに(テープ上では不可能ですからね)、ファイルの新しい内容を2番目のハードリンクの内容として含めたのです。少なくとも、これがこの許可の根拠であり、展開時の意図された動作だと私は信じています。
- JdeBP
著名なtar実装が1つ抜けています。paxmirabilisはtar、cpio、paxをすべて1つにまとめたマルチコールバイナリです。実際、Debianでpaxとして入手できるのはこれです。
* https://mbsd.evolvis.org/pax.htm
* https://manpages.debian.org/trixie/pax/index.html
いいえ、これはlibarchiveのbsdtarではありません。BSDの世界にはtarが1つ以上あるのです。
- bartvk
この人、なんてヒーローなんだ。この「最も難しいtarball」がどんな見た目かを示す小さな図まで載せている。
一番下には、さらに多くのエッジケースへのリンクがある。
これを思い出させる:「Parsing JSON is a Minefield」
- molticrystal
>NET、Julia、uvのtar-codec - これらの実装はtarballを拒否します。技術的にはPOSIX準拠ではないかもしれませんが、これが最善の策だと私は思います。
これが最も安全な選択である一方で、最も役に立たないでもあります。私はアーカイブから何も得られないより、何かしら得られる方を常に好みます。アーカイブの損傷や不規則性はデータの検査を妨げるべきではなく、警告と、抽出できるものに関する注意事項付きのフォールバック手段を提供するべきです。
- zahlman
> このtarballは、私がテストスイートhaampie/tar-minefieldで収集・分類している134個のトリッキーなtarballの1つです。
「tarpit」の方がより自然な名前ではないでしょうか?