`ZipFile.testzip()` Skips Earlier Duplicate Members
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Bug report
Summary
ZipFile.testzip() can incorrectly report that an archive is valid when an earlier member is corrupt and a later member has the same filename. The method iterates over all ZipInfo objects, but opens each one by filename instead of by its ZipInfo instance. Filename lookup selects the last duplicate, so earlier duplicates are checked against the wrong archive entry.
Minimal Reproducer
import io
import struct
import zipfile
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, "w") as zf:
zf.writestr("duplicate.txt", b"corrupt me")
zf.writestr("duplicate.txt", b"valid data")
raw = bytearray(buffer.getvalue())
# Corrupt the payload of the first duplicate only.
with zipfile.ZipFile(io.BytesIO(raw)) as zf:
first = zf.infolist()[0]
name_length, extra_length = struct.unpack_from(
"<HH", raw, first.header_offset + 26
)
data_offset = (
first.header_offset + zipfile.sizeFileHeader +
name_length + extra_length
)
raw[data_offset] ^= 1
with zipfile.ZipFile(io.BytesIO(raw)) as zf:
first = zf.infolist()[0]
try:
zf.read(first)
except zipfile.BadZipFile:
print("The first duplicate is corrupt")
print(zf.testzip())
Observed output:
The first duplicate is corrupt
None
testzip() should return "duplicate.txt".
Expected Behavior
Every member in infolist() should be validated individually. For duplicate names, testzip() should preserve the identity of each ZipInfo object and open the entry with:
self.open(zinfo, "r")
Rather than:
self.open(zinfo.filename, "r")
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-156540
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par ZipFile.testzip et comparez son comportement actuel d’ouverture des entrées avec le reproducer concernant les membres en double dans l’issue. Exécutez le reproducer et les tests zipfile pertinents ; le travail est terminé lorsque chaque ZipInfo est vérifié individuellement et que le doublon antérieur corrompu est signalé comme duplicate.txt.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 35/100