title: Python: BadZipFile even though zip is fine
body: <p>I have these two functions. The first one decrypts a zip file and unzips it in a temporary dir. The second one re-zips, re-encrypts and copies the file back to the original directory. They are chained together in the program (the file is decrypted when the program is run, and then encrypted again right before it exits)</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>When using a new file, both of these work fine. The file gets encrypted and decrypted properly. The second time around however, I always get the same error:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>which then trips the function's error handler:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>If I pause the execution of the encryption function right before the files are removed, and try to open the zip file with 7zip, it works just fine. All the files inside are intact.
  Here are my zip functions in case they help:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Any idea what may be causing the error?</p>
  
  <p>EDIT: Also, since opening the archive with 7zip proves that it is ok, would it be possible to tell zipfile to continue despite the error?</p>