bpo-6584: Add a BadGzipFile exception to the gzip module. (GH-13022)
Co-Authored-By: Filip Gruszczyński <gruszczy@gmail.com> Co-Authored-By: Michele Orrù <maker@tumbolandia.net>
This commit is contained in:
parent
d28772ab69
commit
cf599f6f6f
|
@ -59,6 +59,14 @@ The module defines the following items:
|
|||
.. versionchanged:: 3.6
|
||||
Accepts a :term:`path-like object`.
|
||||
|
||||
.. exception:: BadGzipFile
|
||||
|
||||
An exception raised for invalid gzip files. It inherits :exc:`OSError`.
|
||||
:exc:`EOFError` and :exc:`zlib.error` can also be raised for invalid gzip
|
||||
files.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None)
|
||||
|
||||
Constructor for the :class:`GzipFile` class, which simulates most of the
|
||||
|
|
|
@ -304,6 +304,11 @@ gzip
|
|||
Added the *mtime* parameter to :func:`gzip.compress` for reproducible output.
|
||||
(Contributed by Guo Ci Teo in :issue:`34898`.)
|
||||
|
||||
A :exc:`~gzip.BadGzipFile` exception is now raised instead of :exc:`OSError`
|
||||
for certain types of invalid or corrupt gzip files.
|
||||
(Contributed by Filip Gruszczyński, Michele Orrù, and Zackery Spytz in
|
||||
:issue:`6584`.)
|
||||
|
||||
|
||||
idlelib and IDLE
|
||||
----------------
|
||||
|
|
17
Lib/gzip.py
17
Lib/gzip.py
|
@ -11,7 +11,7 @@ import builtins
|
|||
import io
|
||||
import _compression
|
||||
|
||||
__all__ = ["GzipFile", "open", "compress", "decompress"]
|
||||
__all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"]
|
||||
|
||||
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
|
||||
|
||||
|
@ -112,6 +112,11 @@ class _PaddedFile:
|
|||
def seekable(self):
|
||||
return True # Allows fast-forwarding even in unseekable streams
|
||||
|
||||
|
||||
class BadGzipFile(OSError):
|
||||
"""Exception raised in some cases for invalid gzip files."""
|
||||
|
||||
|
||||
class GzipFile(_compression.BaseStream):
|
||||
"""The GzipFile class simulates most of the methods of a file object with
|
||||
the exception of the truncate() method.
|
||||
|
@ -413,12 +418,12 @@ class _GzipReader(_compression.DecompressReader):
|
|||
return False
|
||||
|
||||
if magic != b'\037\213':
|
||||
raise OSError('Not a gzipped file (%r)' % magic)
|
||||
raise BadGzipFile('Not a gzipped file (%r)' % magic)
|
||||
|
||||
(method, flag,
|
||||
self._last_mtime) = struct.unpack("<BBIxx", self._read_exact(8))
|
||||
if method != 8:
|
||||
raise OSError('Unknown compression method')
|
||||
raise BadGzipFile('Unknown compression method')
|
||||
|
||||
if flag & FEXTRA:
|
||||
# Read & discard the extra field, if present
|
||||
|
@ -502,10 +507,10 @@ class _GzipReader(_compression.DecompressReader):
|
|||
# stored is the true file size mod 2**32.
|
||||
crc32, isize = struct.unpack("<II", self._read_exact(8))
|
||||
if crc32 != self._crc:
|
||||
raise OSError("CRC check failed %s != %s" % (hex(crc32),
|
||||
hex(self._crc)))
|
||||
raise BadGzipFile("CRC check failed %s != %s" % (hex(crc32),
|
||||
hex(self._crc)))
|
||||
elif isize != (self._stream_size & 0xffffffff):
|
||||
raise OSError("Incorrect length of data produced")
|
||||
raise BadGzipFile("Incorrect length of data produced")
|
||||
|
||||
# Gzip files can be padded with zeroes and still have archives.
|
||||
# Consume all zero bytes and set the file position to the first
|
||||
|
|
|
@ -391,6 +391,15 @@ class TestGzip(BaseTest):
|
|||
d = f.read()
|
||||
self.assertEqual(d, data1 * 50, "Incorrect data in file")
|
||||
|
||||
def test_gzip_BadGzipFile_exception(self):
|
||||
self.assertTrue(issubclass(gzip.BadGzipFile, OSError))
|
||||
|
||||
def test_bad_gzip_file(self):
|
||||
with open(self.filename, 'wb') as file:
|
||||
file.write(data1 * 50)
|
||||
with gzip.GzipFile(self.filename, 'r') as file:
|
||||
self.assertRaises(gzip.BadGzipFile, file.readlines)
|
||||
|
||||
def test_non_seekable_file(self):
|
||||
uncompressed = data1 * 50
|
||||
buf = UnseekableIO()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Add a :exc:`~gzip.BadGzipFile` exception to the :mod:`gzip` module.
|
Loading…
Reference in New Issue