Python:BadZipFile即使zip很好

时间:2015-04-09 09:06:36

标签: python-3.x encryption zip

我有这两个功能。第一个解密zip文件并在临时目录中解压缩。第二个重新压缩,重新加密并将文件复制回原始目录。它们在程序中链接在一起(文件在程序运行时被解密,然后在它退出之前再次加密)

def unzip_instance_to_temp(self):
    #Get PS file, copy to temp folder, unzip and delete original (the one that was unzipped, not the one in instances)
    from shutil import copy #used to copy zip file
    os.chdir('instances')
    try:
        copy(program_Config.instance_filename, PS_TEMPORARY_DIR) #PS_TEMPORARY_DIR is the path of the temporary directory
    except FileNotFoundError:
        raise PSError('INSTANCE FILE (AS WRITTEN IN CONFIG) DOES NOT EXIST')
    os.chdir(PS_TEMPORARY_DIR)
    try:
        PSUtils_MAIN.unzip(program_Config.instance_filename_zipversion, '')
    except (zipfile.BadZipFile, FileNotFoundError): #BadZipFile is raised if it cannot be opened (probably encrypted, but keeps unencrypted ones from being put through)
        with open(program_Config.instance_filename, 'rb') as in_file, open(program_Config.instance_filename_zipversion, 'wb') as out_file:
            PSUtils_MAIN.decrypt(in_file, out_file, instance_encryption_key) #instance_encryption_key is a global (it is used across the program)
        try:
            PSUtils_MAIN.unzip(program_Config.instance_filename_zipversion, '')
        except zipfile.BadZipFile: #BadZipFile is raised if it cannot be opened (incorrect encryption key or corrupt file)
            raise PS_INSTANCE_ERROR('UNABLE TO DECODE INSTANCE (WRONG SECURITY KEY OR CORRUPT FILE)')
    os.remove(program_Config.instance_filename) #original encrypted file is deleted
    os.remove(program_Config.instance_filename_zipversion) #original zip is deleted
    #only files left in the temporary dir are the contents of the original zip

def rezip_instance(self):
    #Rezip contents of temporary dir, encrypt, copy back to original dir, delete temporary
    from shutil import rmtree, copy
    os.chdir('..')
    PSUtils_MAIN.zip(PS_TEMPORARY_DIR, program_Config.instance_filename.rstrip('.ps'))
    with open(program_Config.instance_filename_zipversion, 'rb') as in_file, open(program_Config.instance_filename, 'wb') as out_file:
        PSUtils_MAIN.encrypt(in_file, out_file, instance_encryption_key)
    copy(program_Config.instance_filename, program_Config.instances_path)
    os.chdir(program_Config.instances_path)

使用新文件时,这两种方法都可以。该文件被正确加密和解​​密。然而,第二次,我总是得到同样的错误:

Traceback (most recent call last):
  File "E:\Projects\PySec\CurrentVersion\ps.py", line 670, in     unzip_instance_to_temp
    PSUtils_MAIN.unzip(program_Config.instance_filename_zipversion, '')
  File "E:\Projects\PySec\CurrentVersion\ps.py", line 504, in unzip
    zf.extract(member, path)
  File "C:\Python34\lib\zipfile.py", line 1228, in extract
    return self._extract_member(member, path, pwd)
  File "C:\Python34\lib\zipfile.py", line 1290, in _extract_member
    with self.open(member, pwd=pwd) as source, \
  File "C:\Python34\lib\zipfile.py", line 1154, in open
    raise BadZipFile("Truncated file header")
zipfile.BadZipFile: Truncated file header

然后跳转函数的错误处理程序:

Traceback (most recent call last):
  File "E:\Projects\PySec\CurrentVersion\ps.py", line 972, in execute
    core = PSCore()
  File "E:\Projects\PySec\CurrentVersion\ps.py", line 649, in __init__
    self.unzip_instance_to_temp()
  File "E:\Projects\PySec\CurrentVersion\ps.py", line 672, in unzip_instance_to_temp
    raise PS_INSTANCE_ERROR('UNABLE TO DECODE INSTANCE (WRONG SECURITY KEY OR CORRUPT FILE)')
PS_INSTANCE_ERROR: UNABLE TO DECODE INSTANCE (WRONG SECURITY KEY OR CORRUPT FILE)

如果我在删除文件之前暂停加密功能的执行,并尝试用7zip打开zip文件,它就可以了。里面的所有文件都完好无损。 以下是我的zip功能,以防他们提供帮助:

def zip(src, dst):
    #zip files in src directory to a zip with filename dst
    zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)
    abs_src = os.path.abspath(src)
    for dirname, subdirs, files in os.walk(src):
        for filename in files:
            absname = os.path.abspath(os.path.join(dirname, filename))
            arcname = absname[len(abs_src) + 1:]
            zf.write(absname, arcname)
    zf.close()

def unzip(source_filename, dest_dir):
    #unzip a zipfile of source_filename to directory dest_dir
    #path traversal protected
    with zipfile.ZipFile(source_filename) as zf:
        for member in zf.infolist():
            words = member.filename.split('/')
            path = dest_dir
            for word in words[:-1]:
                drive, word = os.path.splitdrive(word)
                head, word = os.path.split(word)
                if word in (os.curdir, os.pardir, ''): continue
                path = os.path.join(path, word)
            zf.extract(member, path)

知道可能导致错误的原因是什么?

编辑:此外,由于用7zip打开存档证明它没问题,尽管有错误,是否可以告诉zipfile继续?

0 个答案:

没有答案