python / python/cpython

`ZipFile.testzip()` Skips Earlier Duplicate Members

Aperta
#156,539 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

stdlib type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da ZipFile.testzip e confronta il suo comportamento attuale nell’apertura delle entry con il reproducer dei membri duplicati nell’issue. Esegui il reproducer e i test zipfile pertinenti; completato significa che ogni ZipInfo viene verificato individualmente e che il duplicato precedente corrotto viene segnalato come duplicate.txt.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
backend
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.