tarfile: don't interpret GNU-style atime as ustar-style path prefix
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 77.2k
- Fork
- 35.9k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
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
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia in Lib/tarfile.py, nell’analisi del prefisso e nell’assegnazione di obj.name in corrispondenza delle righe indicate, quindi riproduci il problema con l’MRE fornito. Il lavoro è completato quando l’archivio GNU-format restituisce ['victim'] invece di ['00000000001/victim']; controlla il PR collegato gh-155706 prima di iniziare.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- tooling
- Tipo di issue
- Bug
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 35/100