Author: Armin Rigo <[email protected]>
Branch: py3.6
Changeset: r97765:3a35a0ae4463
Date: 2019-10-12 12:38 +0200
http://bitbucket.org/pypy/pypy/changeset/3a35a0ae4463/
Log: #3090: lzma sometimes fails to decompress a file
Fixed by back-porting CPython commit
a3c53a1b45b05bcb69660eac5a271443b37ecc42
diff --git a/lib_pypy/_lzma.py b/lib_pypy/_lzma.py
--- a/lib_pypy/_lzma.py
+++ b/lib_pypy/_lzma.py
@@ -583,8 +583,16 @@
self.clear_input_buffer()
elif lzs.avail_in == 0:
# completed successfully!
- self.needs_input = True
lzs.next_in = ffi.NULL
+ if lzs.avail_out == 0:
+ # (avail_in==0 && avail_out==0)
+ # Maybe lzs's internal state still have a few bytes can
+ # be output, try to output them next time.
+ self.needs_input = False
+ assert max_length >= 0 # if < 0, lzs.avail_out always > 0
+ else:
+ # Input buffer exhausted, output buffer has space.
+ self.needs_input = True
self.clear_input_buffer()
else:
self.needs_input = False
@@ -599,9 +607,6 @@
lzs.next_in = buf
lzs.avail_in = buf_len
- if buf_len == 0:
- return b""
-
bufsiz = self._bufsiz
if not (max_length < 0 or max_length > io.DEFAULT_BUFFER_SIZE):
bufsiz = max_length
@@ -616,7 +621,8 @@
try:
while True:
- ret = catch_lzma_error(m.lzma_code, lzs, m.LZMA_RUN)
+ ret = catch_lzma_error(m.lzma_code, lzs, m.LZMA_RUN,
+ ignore_buf_error=(lzs.avail_in == 0 and lzs.avail_out > 0))
data_size = int(ffi.cast('uintptr_t', lzs.next_out)) -
int(ffi.cast('uintptr_t', orig_out))
# data_size is the amount lzma_code has already outputted
@@ -626,10 +632,11 @@
if ret == m.LZMA_STREAM_END:
self.eof = True
break
- elif lzs.avail_in == 0:
- # it ate everything
- break
elif lzs.avail_out == 0:
+ # Need to check lzs->avail_out before lzs->avail_in.
+ # Maybe lzs's internal state still have a few bytes
+ # can be output, grow the output buffer and continue
+ # if max_lengh < 0.
if data_size == max_length:
break
# ran out of space in the output buffer, let's grow it
@@ -647,6 +654,9 @@
lzs.next_out = orig_out + data_size
lzs.avail_out = bufsiz - data_size
+ elif lzs.avail_in == 0:
+ # it ate everything
+ break
result = ffi.buffer(orig_out, data_size)[:]
finally:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit