*** zipfile.latest Thu Sep 19 14:10:58 2002 --- zipfile.new Thu Sep 19 14:42:18 2002 *************** *** 66,87 **** _FH_EXTRA_FIELD_LENGTH = 11 def is_zipfile(filename): ! """Quickly see if file is a ZIP file by checking the magic number. ! ! Will not accept a ZIP archive with an ending comment. ! """ try: fpin = open(filename, "rb") ! fpin.seek(-22, 2) # Seek to end-of-file record ! endrec = fpin.read() fpin.close() ! if endrec[0:4] == "PK005円006円" and endrec[-2:] == "000円000円": return True # file has correct magic number except IOError: pass return False class ZipInfo: """Class with attributes describing each file in the ZIP archive.""" --- 66,117 ---- _FH_EXTRA_FIELD_LENGTH = 11 def is_zipfile(filename): ! """Quickly see if file is a ZIP file by checking the magic number.""" try: fpin = open(filename, "rb") ! endrec = _EndRecData(fpin) fpin.close() ! if endrec: return True # file has correct magic number except IOError: pass return False + def _EndRecData(fpin): + """Return data from the "End of Central Directory" record, or None. + The data is a list of the nine items in the ZIP "End of central dir" + record followed by a tenth item, the file seek offset of this record.""" + fpin.seek(-22, 2) # Assume no archive comment. + filesize = fpin.tell() + 22 # Get file size + data = fpin.read() + if data[0:4] == stringEndArchive and data[-2:] == "000円000円": + endrec = struct.unpack(structEndArchive, data) + endrec = list(endrec) + endrec.append("") # Append the archive comment + endrec.append(filesize - 22) # Append the record start offset + return endrec + # Search the last END_BLOCK bytes of the file for the record signature. + # The comment is appended to the ZIP file and has a 16 bit length. + # So the comment may be up to 64K long. We limit the search for the + # signature to a few Kbytes at the end of the file for efficiency. + # also, the signature must not appear in the comment. + END_BLOCK = min(filesize, 1024 * 4) + fpin.seek(filesize - END_BLOCK, 0) + data = fpin.read() + start = data.rfind(stringEndArchive) + if start>= 0: # Correct signature string was found + endrec = struct.unpack(structEndArchive, data[start:start+22]) + endrec = list(endrec) + comment = data[start+22:] + if endrec[7] == len(comment): # Comment length checks out + # Append the archive comment and start offset + endrec.append(comment) + endrec.append(filesize - END_BLOCK + start) + return endrec + return # Error, return None + + class ZipInfo: """Class with attributes describing each file in the ZIP archive.""" *************** *** 183,198 **** elif key == 'w': pass elif key == 'a': ! fp = self.fp ! fp.seek(-22, 2) # Seek to end-of-file record ! endrec = fp.read() ! if endrec[0:4] == stringEndArchive and \ ! endrec[-2:] == "000円000円": ! self._GetContents() # file is a zip file # seek to start of directory and overwrite ! fp.seek(self.start_dir, 0) ! else: # file is not a zip file, just append ! fp.seek(0, 2) else: if not self._filePassed: self.fp.close() --- 213,224 ---- elif key == 'w': pass elif key == 'a': ! try: # See if file is a zip file ! self._RealGetContents() # seek to start of directory and overwrite ! self.fp.seek(self.start_dir, 0) ! except BadZipfile: # file is not a zip file, just append ! self.fp.seek(0, 2) else: if not self._filePassed: self.fp.close() *************** *** 213,229 **** def _RealGetContents(self): """Read in the table of contents for the ZIP file.""" fp = self.fp ! fp.seek(-22, 2) # Start of end-of-archive record ! filesize = fp.tell() + 22 # Get file size ! endrec = fp.read(22) # Archive must not end with a comment! ! if endrec[0:4] != stringEndArchive or endrec[-2:] != "000円000円": ! raise BadZipfile, "File is not a zip file, or ends with a comment" ! endrec = struct.unpack(structEndArchive, endrec) if self.debug> 1: print endrec size_cd = endrec[5] # bytes in central directory offset_cd = endrec[6] # offset of central directory ! x = filesize - 22 - size_cd # "concat" is zero, unless zip was concatenated to another file concat = x - offset_cd if self.debug> 2: --- 239,254 ---- def _RealGetContents(self): """Read in the table of contents for the ZIP file.""" fp = self.fp ! endrec = _EndRecData(fp) ! if not endrec: ! raise BadZipfile, "File is not a zip file" if self.debug> 1: print endrec size_cd = endrec[5] # bytes in central directory offset_cd = endrec[6] # offset of central directory ! self.comment = endrec[8] # archive comment ! # endrec[9] is the offset of the "End of Central Dir" record ! x = endrec[9] - size_cd # "concat" is zero, unless zip was concatenated to another file concat = x - offset_cd if self.debug> 2:

AltStyle によって変換されたページ (->オリジナル) /