tarfile extraction filters raise raw ValueError for Windows drive-relative paths
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
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
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu với các kiểm tra containment của bộ lọc giải nén tarfile và cách xử lý ntpath.commonpath được mô tả trong issue; tái hiện các trường hợp trên Windows với tên member và đích liên kết như C:bad.txt. Được xem là hoàn tất khi các trường hợp tương đối theo ổ đĩa sử dụng các ngoại lệ tarfile có cấu trúc đã nêu và errorlevel=0 tiếp tục giải nén đến các member tiếp theo; lưu ý rằng PR được liên kết gh-154993 đã có sẵn.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- operating-systems
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 30/100