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)
| 343 | |
| 344 | |
| 345 | def _EndRecData(fpin): |
| 346 | """Return data from the "End of Central Directory" record, or None. |
| 347 | |
| 348 | The data is a list of the nine items in the ZIP "End of central dir" |
| 349 | record followed by a tenth item, the file seek offset of this record.""" |
| 350 | |
| 351 | # Determine file size |
| 352 | fpin.seek(0, 2) |
| 353 | filesize = fpin.tell() |
| 354 | |
| 355 | # Check to see if this is ZIP file with no archive comment (the |
| 356 | # "end of central directory" structure should be the last item in the |
| 357 | # file if this is the case). |
| 358 | try: |
| 359 | fpin.seek(-sizeEndCentDir, 2) |
| 360 | except OSError: |
| 361 | return None |
| 362 | data = fpin.read(sizeEndCentDir) |
| 363 | if (len(data) == sizeEndCentDir and |
| 364 | data[0:4] == stringEndArchive and |
| 365 | data[-2:] == b"\000\000"): |
| 366 | # the signature is correct and there's no comment, unpack structure |
| 367 | endrec = struct.unpack(structEndArchive, data) |
| 368 | endrec=list(endrec) |
| 369 | |
| 370 | # Append a blank comment and record start offset |
| 371 | endrec.append(b"") |
| 372 | endrec.append(filesize - sizeEndCentDir) |
| 373 | |
| 374 | # Try to read the "Zip64 end of central directory" structure |
| 375 | return _EndRecData64(fpin, filesize - sizeEndCentDir, endrec) |
| 376 | |
| 377 | # Either this is not a ZIP file, or it is a ZIP file with an archive |
| 378 | # comment. Search the end of the file for the "end of central directory" |
| 379 | # record signature. The comment is the last item in the ZIP file and may be |
| 380 | # up to 64K long. It is assumed that the "end of central directory" magic |
| 381 | # number does not appear in the comment. |
| 382 | maxCommentStart = max(filesize - ZIP_MAX_COMMENT - sizeEndCentDir, 0) |
| 383 | fpin.seek(maxCommentStart, 0) |
| 384 | data = fpin.read(ZIP_MAX_COMMENT + sizeEndCentDir) |
| 385 | start = data.rfind(stringEndArchive) |
| 386 | if start >= 0: |
| 387 | # found the magic number; attempt to unpack and interpret |
| 388 | recData = data[start:start+sizeEndCentDir] |
| 389 | if len(recData) != sizeEndCentDir: |
| 390 | # Zip file is corrupted. |
| 391 | return None |
| 392 | endrec = list(struct.unpack(structEndArchive, recData)) |
| 393 | commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file |
| 394 | comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] |
| 395 | endrec.append(comment) |
| 396 | endrec.append(maxCommentStart + start) |
| 397 | |
| 398 | # Try to read the "Zip64 end of central directory" structure |
| 399 | return _EndRecData64(fpin, maxCommentStart + start, endrec) |
| 400 | |
| 401 | # Unable to find a valid end of central directory structure |
| 402 | return None |