tarfile extraction filters raise raw ValueError for Windows drive-relative paths
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 35.9k
- PR マージ指標
- PR 指標を取得中
説明
Bug report
Bug description:
tarfile extraction filters raise a raw ValueError on Windows when handling drive-relative member names or link targets such as C:bad.txt.
This looks like an inconsistency in the extraction-filter error handling path. The affected cases are rejected through a raw ValueError from Windows path handling instead of the structured tarfile filter exceptions that similar rejected paths use.
For example, with filter="data" and errorlevel = 0, I expected the invalid member to be skipped/refused and extraction to continue to later members. Instead, extraction aborts with:
ValueError: Paths don't have the same drive
Minimal reproducer:
import io
import os
import tarfile
import tempfile
from pathlib import Path
def add_file(tf, name, data=b"x"):
info = tarfile.TarInfo(name)
info.size = len(data)
tf.addfile(info, io.BytesIO(data))
def build_archive_with_drive_relative_member(path):
with tarfile.open(path, "w") as tf:
add_file(tf, "before.txt", b"before")
add_file(tf, "C:bad.txt", b"bad")
add_file(tf, "after.txt", b"after")
def main():
if os.name != "nt":
print("This reproducer is Windows-specific.")
return 0
with tempfile.TemporaryDirectory() as tmp:
tmp = Path(tmp)
archive_path = tmp / "drive_relative.tar"
extract_dir = tmp / "extract"
extract_dir.mkdir()
build_archive_with_drive_relative_member(archive_path)
try:
with tarfile.open(archive_path, "r") as tf:
tf.errorlevel = 0
tf.extractall(extract_dir, filter="data")
except Exception as exc:
print("exception_type:", type(exc).__name__)
print("exception_message:", str(exc))
print("before_exists:", (extract_dir / "before.txt").exists())
print("after_exists:", (extract_dir / "after.txt").exists())
if __name__ == "__main__":
raise SystemExit(main())
Observed output on Windows:
exception_type: ValueError
exception_message: Paths don't have the same drive
before_exists: True
after_exists: False
Expected behavior:
The drive-relative member should be handled through the normal tarfile extraction-filter exception path, for example OutsideDestinationError, so that errorlevel = 0 can skip/refuse that member and continue extracting later members.
Expected output would be:
before_exists: True
after_exists: True
I also observed the same raw ValueError behavior for drive-relative hardlink and symlink targets under filter="data".
Expected structured exceptions:
Drive-relative member name: OutsideDestinationError
Drive-relative hardlink target: LinkOutsideDestinationError
Drive-relative symlink target: LinkOutsideDestinationError
The issue appears to come from ntpath.commonpath() raising ValueError for incompatible drive/path semantics, and that exception escaping directly instead of being converted into the appropriate tarfile filter exception.
A possible fix would be to treat ValueError from the containment/commonpath check as an outside-destination condition and raise the appropriate structured tarfile exception.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows
Linked PRs
- gh-154993
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
issue に記載されている tarfile 抽出フィルターの包含チェックと ntpath.commonpath の処理から始め、C:bad.txt のようなメンバー名とリンク先を使って Windows 上でケースを再現します。完了条件は、ドライブ相対のケースで指定された構造化された tarfile 例外が使われ、errorlevel=0 によって後続のメンバーへの抽出が続行されることです。リンクされている PR gh-154993 はすでに存在することに注意してください。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- operating-systems
- issue の種類
- バグ
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 30/100