python / python/cpython

tarfile extraction filters raise raw ValueError for Windows drive-relative paths

Đang mở
#154,987 5 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

OS-windows stdlib type-bug
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

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. 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

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.