import binascii
import copy
import errno
+import functools
import io
import mmap
import operator
if read2 != GZ_MAGIC_BYTES:
raise ReadError("not a gzip file")
- read1 = ord (self.__read(1))
- if read1 != GZ_METHOD_DEFLATE:
+ read1 = self.__read(1)
+ if read1 == b"":
+ raise EndOfFile ("_init_read_gz(): read returned zero bytes inside "
+ "gzip header at pos %d" % self.fileobj.tell())
+ if ord (read1) != GZ_METHOD_DEFLATE:
raise CompressionError("unsupported compression method")
self.flags = flag = ord(self.__read(1))
def open_at_offset(cls, offset, *a, **kwa):
"""
Same as ``.open()``, but start reading at the given offset. Assumes a
- seekable file object.
+ seekable file object. Returns *None* if opening failed due to a read
+ problem.
"""
fileobj = kwa.get ("fileobj")
if fileobj is not None:
fileobj.seek (offset)
+
return cls.open (*a, **kwa)
else:
raise RuntimeError
- tarobj = \
- TarFile.open_at_offset (offset,
- mode=mode,
- fileobj=fileobj,
- format=GNU_FORMAT,
- concat='#' in mode,
- encryption=decr,
- save_to_members=False,
- tolerance=TOLERANCE_RESCUE)
+ try:
+ tarobj = \
+ TarFile.open_at_offset (offset,
+ mode=mode,
+ fileobj=fileobj,
+ format=GNU_FORMAT,
+ concat='#' in mode,
+ encryption=decr,
+ save_to_members=False,
+ tolerance=TOLERANCE_RESCUE)
+ except (ReadError, EndOfFile):
+ return None
return tarobj.next ()
nvol = 0
- def aux (o, nvol, ti):
- ie = idxent_of_tarinfo (ti)
- ie ["offset"] = o
- ie ["volume"] = nvol
- return ie
-
while True:
vpath = gen_volume_name (nvol)
try:
break
fileobj = bltn_open (vpath, "rb")
- infos += [ (off, nvol, read_tarobj_at_offset (fileobj, off, mode,
- secret=secret))
- for off in offsets ]
+
+ def aux (acc, off):
+ obj = read_tarobj_at_offset (fileobj, off, mode, secret=secret)
+ if obj is not None:
+ acc.append ((off, nvol, obj))
+ return acc
+ infos += functools.reduce (aux, offsets, [])
+
nvol += 1
+ def aux (o, nvol, ti):
+ ie = idxent_of_tarinfo (ti)
+ ie ["offset"] = o
+ ie ["volume"] = nvol
+ return ie
+
psidx = [ aux (o, nvol, ti) for o, nvol, ti in infos ]
return psidx