python / python/cpython

tarfile: Degenerate TARs with global PAX headers are not handled correctly

Offen
#149,578 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

stdlib type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug report

Bug description:

It appears that tarfile.TarFile fails opening PAX TAR files if the only thing they contain is the global headers, no matter if created with the module or with the tar tool. The exception raised is tarfile.ReadError: end of file header. The tar executable handles those files perfectly.

Reproducer

import subprocess
import traceback
import tarfile
import sys
import io

#
# Non-empty Python-created files work
#
filename = "non_empty_python.tar"
with tarfile.TarFile(filename,
                     mode="w",
                     format=tarfile.PAX_FORMAT,
                     pax_headers=dict(abc="def")
) as t:
    t.addfile(tarfile.TarInfo("ghi.txt"), io.BytesIO(b"ghi"))
subprocess.check_call(["tar", "tf", filename],
                      stdout=subprocess.DEVNULL)
with tarfile.TarFile(filename, mode="a"):
    pass

#
# Non-empty tar-created files work
#
filename = "non_empty_tar.tar"
subprocess.check_call(["/bin/bash", "-c", f"""
    tar -c -H pax --pax-option='foo=bar' -f {filename} \
        -P --transform 's/.*/ghi.txt/' <(echo ghi)
"""])
subprocess.check_call(["tar", "tf", filename],
                      stdout=subprocess.DEVNULL)
with tarfile.TarFile(filename, mode="a"):
    pass

#
# Empty Python-created files break
#
filename = "empty_python.tar"
with tarfile.TarFile(filename,
                     mode="w",
                     format=tarfile.PAX_FORMAT,
                     pax_headers=dict(abc="def")
) as t:
    pass
subprocess.check_call(["tar", "tf", filename],
                      stdout=subprocess.DEVNULL)
try:
    with tarfile.TarFile(filename, mode="a"):
        pass
except Exception:
    print(f"Opening empty Python-created PAX TAR {filename!r} failed:",
          file=sys.stderr)
    print(traceback.format_exc(), file=sys.stderr)

#
# Empty tar-created files break
#
filename = "empty_tar.tar"
subprocess.check_call(["/bin/bash", "-c", f"""
    tar -c -H pax --pax-option='foo=bar' -f {filename} \
        --files-from=/dev/null
"""])
subprocess.check_call(["tar", "tf", filename],
                      stdout=subprocess.DEVNULL)
try:
    with tarfile.TarFile(filename, mode="a"):
        pass
except Exception:
    print(f"Opening empty tar-created PAX TAR {filename!r} failed:",
          file=sys.stderr)
    print(traceback.format_exc(), file=sys.stderr)
CPython versions tested on:

3.15

Operating systems tested on:

Linux

Linked PRs
  • gh-149647
  • gh-156792

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem Reproducer und dem Öffnungspfad von tarfile.TarFile im Anhängemodus, mit Fokus auf Archive, die ausschließlich globale PAX-Header enthalten. Füge Regressionstests sowohl für von Python erstellte als auch für von tar erstellte leere PAX-Archive hinzu und verifiziere, dass ihr Öffnen im Modus "a" ohne einen ReadError erfolgreich ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
tooling
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.