python / python/cpython

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

Abierto
#154,987 5 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

OS-windows stdlib type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comience con las comprobaciones de contención del filtro de extracción de tarfile y el manejo de ntpath.commonpath descritos en el issue; reproduzca los casos en Windows con nombres de miembros y destinos de enlaces como C:bad.txt. Se considera completado cuando los casos relativos a la unidad usan las excepciones estructuradas de tarfile indicadas y errorlevel=0 continúa la extracción con los miembros posteriores; tenga en cuenta que el PR vinculado gh-154993 ya está presente.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
operating-systems
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
30/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.