python / python/cpython

`ZipFile.testzip()` Skips Earlier Duplicate Members

Aberta
#156,539 0 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

stdlib type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
36k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

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

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece em ZipFile.testzip e compare seu comportamento atual de abertura de entradas com o reproducer de membros duplicados da issue. Execute o reproducer e os testes relevantes de zipfile; concluído significa que cada ZipInfo é verificado individualmente e que o duplicado corrompido anterior é reportado como duplicate.txt.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
backend
Tipo de issue
Bug
Dificuldade
2/5
Tempo estimado
1-3 horas
Status de atividade
Estagnada
Clareza
Claramente especificada
Facilidade para iniciantes
35/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.