Skip to content

Commit e61bccf

Browse files
committed
Refactor by splitting gzip and non-gzip branch
1 parent 42a7a3d commit e61bccf

1 file changed

Lines changed: 34 additions & 17 deletions

File tree

Lib/tarfile.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -542,26 +542,43 @@ def _read(self, size):
542542
c = 0
543543
t = []
544544
while c < size:
545-
# Skip underlying buffer to avoid unaligned double buffering.
546-
if self.buf:
547-
buf = self.buf
548-
self.buf = b""
549-
elif self.comptype != "gz" and not self.cmp.needs_input:
550-
buf = b""
551-
else:
552-
buf = self.fileobj.read(self.bufsize)
553-
if not buf:
554-
break
555-
try:
556-
buf = self.cmp.decompress(buf, size - c)
557-
if self.comptype == "gz":
545+
if self.comptype == "gz":
546+
# zlib interface is different than others.
547+
# It returns data in unconsumed_tail.
548+
if self.buf:
549+
cbuf = self.buf
550+
self.buf = b""
551+
else:
552+
cbuf = self.fileobj.read(self.bufsize)
553+
if not cbuf:
554+
break
555+
556+
try:
557+
dbuf = self.cmp.decompress(cbuf, size - c)
558558
self.buf = self.cmp.unconsumed_tail
559-
except self.exception as e:
560-
raise ReadError("invalid compressed data") from e
561-
t.append(buf)
562-
c += len(buf)
559+
except self.exception as e:
560+
raise ReadError("invalid compressed data") from e
561+
else:
562+
# Other decompressors have needs_input.
563+
# decompress() can buffer data internally.
564+
if self.cmp.needs_input:
565+
cbuf = self.fileobj.read(self.bufsize)
566+
if not cbuf:
567+
break
568+
else:
569+
cbuf = b""
570+
571+
try:
572+
dbuf = self.cmp.decompress(cbuf, size - c)
573+
except self.exception as e:
574+
raise ReadError("invalid compressed data") from e
575+
576+
t.append(dbuf)
577+
c += len(dbuf)
578+
563579
t = b"".join(t)
564580
if len(t) > size:
581+
# This would only happen if decompress() has a bug.
565582
raise ReadError("decompress() returned too much data")
566583
return t
567584

0 commit comments

Comments
 (0)