tarfile: don't interpret GNU-style atime as ustar-style path prefix
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug report
Bug description:
The GNU and ustar tar format families have slightly overlapping header definitions: ustar says that bytes 345:500 are used for the "path prefix" i.e. for paths longer than the 100 char limit in the path field, while old-style GNU ("oldgnu") says that 345:356 are used for storing an atime attribute for the member.
Consequently, the two overlap (partially), and a tar parser should check the header's magic to determine how to interpret that byte range.
At the moment, CPython does not use the header's magic, and instead unconditionally interprets that range as a ustar-style prefix:
https://github.com/python/cpython/blob/b11e749f7590e9a0907db908fa3e7e76c772c28f/Lib/tarfile.py#L1354
and then unconditionally uses that prefix as long as the member type (not the header type) isn't a special GNU member type:
The end result of this is that tarfile can extract a file with a surprising name, whereas other parsers extract with the correct (non-ustar-prefixed) name.
MRE:
import io
import tarfile
member = tarfile.TarInfo("victim")
header = bytearray(member.tobuf(format=tarfile.GNU_FORMAT))
# Old-GNU atime field: valid octal timestamp 1.
header[345:357] = b"00000000001\0"
# Recalculate checksum.
header[148:156] = b" " * 8
header[148:156] = f"{sum(header):06o}\0 ".encode("ascii")
archive = bytes(header) + b"\0" * 1024
with tarfile.open(fileobj=io.BytesIO(archive), mode="r:") as tf:
print(tf.getnames())
On a main build as of b11e749f7590e9a0907db908fa3e7e76c772c28f, this produces:
['00000000001/victim']
whereas the output should be ['victim'], since the format is GNU_FORMAT instead of a ustar-family format.
I think the fix for this is to tweak the obj.name assignment to only use prefix when the magic bytes match POSIX_MAGIC, i.e. not GNU_MAGIC or any legacy (v7, pre-ustar) magic.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Linked PRs
- gh-155706
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne in Lib/tarfile.py bei der Präfixanalyse und der Zuweisung von obj.name rund um die referenzierten Zeilen und reproduziere dann das Problem mit dem bereitgestellten MRE. Als erledigt gilt, wenn das GNU-format-Archiv ['victim'] statt ['00000000001/victim'] zurückgibt; prüfe den verknüpften PR gh-155706, bevor du beginnst.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- tooling
- Issue-Typ
- Bug
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100