mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
#15546: Fix {GzipFile,LZMAFile}.read1()'s handling of pathological input data.
This commit is contained in:
parent
9c92a691e1
commit
37d3ff1487
3 changed files with 33 additions and 22 deletions
|
@ -385,7 +385,10 @@ class GzipFile(io.BufferedIOBase):
|
||||||
return b''
|
return b''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._read()
|
# For certain input data, a single call to _read() may not return
|
||||||
|
# any data. In this case, retry until we get some data or reach EOF.
|
||||||
|
while self.extrasize <= 0:
|
||||||
|
self._read()
|
||||||
except EOFError:
|
except EOFError:
|
||||||
pass
|
pass
|
||||||
if size < 0 or size > self.extrasize:
|
if size < 0 or size > self.extrasize:
|
||||||
|
|
47
Lib/lzma.py
47
Lib/lzma.py
|
@ -204,29 +204,31 @@ class LZMAFile(io.BufferedIOBase):
|
||||||
|
|
||||||
# Fill the readahead buffer if it is empty. Returns False on EOF.
|
# Fill the readahead buffer if it is empty. Returns False on EOF.
|
||||||
def _fill_buffer(self):
|
def _fill_buffer(self):
|
||||||
if self._buffer:
|
# Depending on the input data, our call to the decompressor may not
|
||||||
return True
|
# return any data. In this case, try again after reading another block.
|
||||||
|
while True:
|
||||||
|
if self._buffer:
|
||||||
|
return True
|
||||||
|
|
||||||
if self._decompressor.unused_data:
|
if self._decompressor.unused_data:
|
||||||
rawblock = self._decompressor.unused_data
|
rawblock = self._decompressor.unused_data
|
||||||
else:
|
|
||||||
rawblock = self._fp.read(_BUFFER_SIZE)
|
|
||||||
|
|
||||||
if not rawblock:
|
|
||||||
if self._decompressor.eof:
|
|
||||||
self._mode = _MODE_READ_EOF
|
|
||||||
self._size = self._pos
|
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
raise EOFError("Compressed file ended before the "
|
rawblock = self._fp.read(_BUFFER_SIZE)
|
||||||
"end-of-stream marker was reached")
|
|
||||||
|
|
||||||
# Continue to next stream.
|
if not rawblock:
|
||||||
if self._decompressor.eof:
|
if self._decompressor.eof:
|
||||||
self._decompressor = LZMADecompressor(**self._init_args)
|
self._mode = _MODE_READ_EOF
|
||||||
|
self._size = self._pos
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
raise EOFError("Compressed file ended before the "
|
||||||
|
"end-of-stream marker was reached")
|
||||||
|
|
||||||
self._buffer = self._decompressor.decompress(rawblock)
|
# Continue to next stream.
|
||||||
return True
|
if self._decompressor.eof:
|
||||||
|
self._decompressor = LZMADecompressor(**self._init_args)
|
||||||
|
|
||||||
|
self._buffer = self._decompressor.decompress(rawblock)
|
||||||
|
|
||||||
# Read data until EOF.
|
# Read data until EOF.
|
||||||
# If return_data is false, consume the data without returning it.
|
# If return_data is false, consume the data without returning it.
|
||||||
|
@ -284,11 +286,14 @@ class LZMAFile(io.BufferedIOBase):
|
||||||
return self._read_block(size)
|
return self._read_block(size)
|
||||||
|
|
||||||
def read1(self, size=-1):
|
def read1(self, size=-1):
|
||||||
"""Read up to size uncompressed bytes with at most one read
|
"""Read up to size uncompressed bytes, while trying to avoid
|
||||||
from the underlying stream.
|
making multiple reads from the underlying stream.
|
||||||
|
|
||||||
Returns b"" if the file is at EOF.
|
Returns b"" if the file is at EOF.
|
||||||
"""
|
"""
|
||||||
|
# Usually, read1() calls _fp.read() at most once. However, sometimes
|
||||||
|
# this does not give enough data for the decompressor to make progress.
|
||||||
|
# In this case we make multiple reads, to avoid returning b"".
|
||||||
self._check_can_read()
|
self._check_can_read()
|
||||||
if (size == 0 or self._mode == _MODE_READ_EOF or
|
if (size == 0 or self._mode == _MODE_READ_EOF or
|
||||||
not self._fill_buffer()):
|
not self._fill_buffer()):
|
||||||
|
|
|
@ -77,6 +77,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #15546: Fix handling of pathological input data in the read1() method of
|
||||||
|
the BZ2File, GzipFile and LZMAFile classes.
|
||||||
|
|
||||||
- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog
|
- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog
|
||||||
ended with '\'. Patch by Roger Serwy.
|
ended with '\'. Patch by Roger Serwy.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue