zipfile не может обработать некоторые типы данных zip? - PullRequest
7 голосов
/ 07 февраля 2011

Я столкнулся с этой проблемой, пытаясь распаковать zip-файл.

- zipfile.is_zipfile(my_file) всегда возвращает False, даже если команда UNIX unzip справляется с этим просто отлично. Также при попытке сделать zipfile.ZipFile(path/file_handle_to_path) я получаю ту же ошибку

- команда file возвращает Zip archive data, at least v2.0 to extract и использует less в файле, который она показывает:

PKZIP for iSeries by PKWARE Length Method Size Cmpr Date Time CRC-32 Name 2113482674 Defl:S 204502989 90% 2010-11-01 08:39 2cee662e myfile.txt 2113482674 204502989 90% 1 file

Есть идеи, как мне обойти эту проблему? Было бы неплохо, если бы я мог заставить работать zipfile в Python, поскольку у меня уже есть несколько модульных тестов, которые мне придется отбросить, если я переключусь на запуск subprocess.call("unzip")

Ответы [ 3 ]

5 голосов
/ 18 сентября 2011

Наткнулся на ту же проблему на моих файлах и смог ее решить.Я не уверен, как они были сгенерированы, как в приведенном выше примере.В конце концов все они имели конечные данные, игнорируемые Windows 7z и zip-файлом Python.

Это код для решения проблемы:

def fixBadZipfile(zipFile):  
     f = open(zipFile, 'r+b')  
     data = f.read()  
     pos = data.find('\x50\x4b\x05\x06') # End of central directory signature  
     if (pos > 0):  
         self._log("Truncating file at location " + str(pos + 22) + ".")  
         f.seek(pos + 22)   # size of 'ZIP end of central directory record' 
         f.truncate()  
         f.close()  
     else:  
         # raise error, file is truncated  
1 голос
/ 05 апреля 2011

Вы говорите, используя less в файле, который показывает то-то и то-то.Вы имеете в виду это?

less my_file

Если это так, я бы предположил, что это комментарии, которые программа zip поместила в файл.Глядя на руководство пользователя для iSeries PKZIP, которое я нашел в Интернете, это поведение по умолчанию.

Документы для zipfile говорят: "Этот модуль в настоящее время не обрабатывает ZIP-файлы, к которым добавлены комментарии."Возможно, это проблема?(Конечно, если less показывает их, это может означать, что они с добавлением , FWIW.)

Кажется, вы (или кто-либо, кто создавал zip-файл на машине iSeries) может отключить это с помощью ARCHTEXT(*NONE), или использовать ARCHTEXT(*CLEAR), чтобы удалить его из существующего zipfile.

0 голосов
/ 10 декабря 2018
# Utilize mmap module to avoid a potential DoS exploit (e.g. by reading the
# whole zip file into memory). A bad zip file example can be found here:
# https://bugs.python.org/issue24621

import mmap
from io import UnsupportedOperation
from zipfile import BadZipfile

# The end of central directory signature
CENTRAL_DIRECTORY_SIGNATURE = b'\x50\x4b\x05\x06'


def repair_central_directory(zipFile):
    if hasattr(zipFile, 'read'):
        # This is a file-like object
        f = zipFile
        try:
            fileno = f.fileno()
        except UnsupportedOperation:
            # This is an io.BytesIO instance which lacks a backing file.
            fileno = None
    else:
        # Otherwise, open the file with binary mode
        f = open(zipFile, 'rb+')
        fileno = f.fileno()
    if fileno is None:
        # Without a fileno, we can only read and search the whole string
        # for the end of central directory signature.
        f.seek(0)
        pos = f.read().find(CENTRAL_DIRECTORY_SIGNATURE)
    else:
        # Instead of reading the entire file into memory, memory-mapped the
        # file, then search it for the end of central directory signature.
        # Reference: https://stackoverflow.com/a/21844624/2293304
        mm = mmap.mmap(fileno, 0)
        pos = mm.find(CENTRAL_DIRECTORY_SIGNATURE)
        mm.close()
    if pos > -1:
        # size of 'ZIP end of central directory record'
        f.truncate(pos + 22)
        f.seek(0)
        return f
    else:
        # Raise an error to make it fail fast
        raise BadZipfile('File is not a zip file')
...