Read the ZIP64 end-of-archive records and use that to update endrec
(fpin, offset, endrec)
| 283 | return offset_cd, concat |
| 284 | |
| 285 | def _EndRecData64(fpin, offset, endrec): |
| 286 | """ |
| 287 | Read the ZIP64 end-of-archive records and use that to update endrec |
| 288 | """ |
| 289 | offset -= sizeEndCentDir64Locator |
| 290 | if offset < 0: |
| 291 | # The file is not large enough to contain a ZIP64 |
| 292 | # end-of-archive record, so just return the end record we were given. |
| 293 | return endrec |
| 294 | fpin.seek(offset) |
| 295 | data = fpin.read(sizeEndCentDir64Locator) |
| 296 | if len(data) != sizeEndCentDir64Locator: |
| 297 | raise OSError("Unknown I/O error") |
| 298 | sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data) |
| 299 | if sig != stringEndArchive64Locator: |
| 300 | return endrec |
| 301 | |
| 302 | if diskno != 0 or disks > 1: |
| 303 | raise BadZipFile("zipfiles that span multiple disks are not supported") |
| 304 | |
| 305 | offset -= sizeEndCentDir64 |
| 306 | if reloff > offset: |
| 307 | raise BadZipFile("Corrupt zip64 end of central directory locator") |
| 308 | # First, check the assumption that there is no prepended data. |
| 309 | fpin.seek(reloff) |
| 310 | extrasz = offset - reloff |
| 311 | data = fpin.read(sizeEndCentDir64) |
| 312 | if len(data) != sizeEndCentDir64: |
| 313 | raise OSError("Unknown I/O error") |
| 314 | if not data.startswith(stringEndArchive64) and reloff != offset: |
| 315 | # Since we already have seen the Zip64 EOCD Locator, it's |
| 316 | # possible we got here because there is prepended data. |
| 317 | # Assume no 'zip64 extensible data' |
| 318 | fpin.seek(offset) |
| 319 | extrasz = 0 |
| 320 | data = fpin.read(sizeEndCentDir64) |
| 321 | if len(data) != sizeEndCentDir64: |
| 322 | raise OSError("Unknown I/O error") |
| 323 | if not data.startswith(stringEndArchive64): |
| 324 | raise BadZipFile("Zip64 end of central directory record not found") |
| 325 | |
| 326 | sig, sz, create_version, read_version, disk_num, disk_dir, \ |
| 327 | dircount, dircount2, dirsize, diroffset = \ |
| 328 | struct.unpack(structEndArchive64, data) |
| 329 | if (diroffset + dirsize != reloff or |
| 330 | sz + 12 != sizeEndCentDir64 + extrasz): |
| 331 | raise BadZipFile("Corrupt zip64 end of central directory record") |
| 332 | |
| 333 | # Update the original endrec using data from the ZIP64 record |
| 334 | endrec[_ECD_SIGNATURE] = sig |
| 335 | endrec[_ECD_DISK_NUMBER] = disk_num |
| 336 | endrec[_ECD_DISK_START] = disk_dir |
| 337 | endrec[_ECD_ENTRIES_THIS_DISK] = dircount |
| 338 | endrec[_ECD_ENTRIES_TOTAL] = dircount2 |
| 339 | endrec[_ECD_SIZE] = dirsize |
| 340 | endrec[_ECD_OFFSET] = diroffset |
| 341 | endrec[_ECD_LOCATION] = offset - extrasz |
| 342 | return endrec |
no test coverage detected
searching dependent graphs…