From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 4 Mar 2020 07:06:19 +0000 (-0800) Subject: [3.7] bpo-39389: gzip: fix compression level metadata (GH-18077) (GH-18101) X-Git-Tag: v3.7.7rc1~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=12c45efe828a90a2f2f58a1f95c85d792a0d9c0a;p=thirdparty%2FPython%2Fcpython.git [3.7] bpo-39389: gzip: fix compression level metadata (GH-18077) (GH-18101) * bpo-39389: gzip: fix compression level metadata (GH-18077) As described in RFC 1952, section 2.3.1, the XFL (eXtra FLags) byte of a gzip member header should indicate whether the DEFLATE algorithm was tuned for speed or compression ratio. Prior to this patch, archives emitted by the `gzip` module always indicated maximum compression. (cherry picked from commit eab3b3f1c60afecfb4db3c3619109684cb04bd60) Co-authored-by: William Chargin --- diff --git a/Lib/gzip.py b/Lib/gzip.py index ddc7bda1fecb..e59b45481432 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -17,6 +17,11 @@ FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16 READ, WRITE = 1, 2 +_COMPRESS_LEVEL_FAST = 1 +_COMPRESS_LEVEL_TRADEOFF = 6 +_COMPRESS_LEVEL_BEST = 9 + + def open(filename, mode="rb", compresslevel=9, encoding=None, errors=None, newline=None): """Open a gzip-compressed file in binary or text mode. @@ -191,7 +196,7 @@ class GzipFile(_compression.BaseStream): self.fileobj = fileobj if self.mode == WRITE: - self._write_gzip_header() + self._write_gzip_header(compresslevel) @property def filename(self): @@ -218,7 +223,7 @@ class GzipFile(_compression.BaseStream): self.bufsize = 0 self.offset = 0 # Current file offset for seek(), tell(), etc - def _write_gzip_header(self): + def _write_gzip_header(self, compresslevel): self.fileobj.write(b'\037\213') # magic header self.fileobj.write(b'\010') # compression method try: @@ -239,7 +244,13 @@ class GzipFile(_compression.BaseStream): if mtime is None: mtime = time.time() write32u(self.fileobj, int(mtime)) - self.fileobj.write(b'\002') + if compresslevel == _COMPRESS_LEVEL_BEST: + xfl = b'\002' + elif compresslevel == _COMPRESS_LEVEL_FAST: + xfl = b'\004' + else: + xfl = b'\000' + self.fileobj.write(xfl) self.fileobj.write(b'\377') if fname: self.fileobj.write(fname + b'\000') diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 17ecda2089f2..0251914d8bca 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -358,6 +358,26 @@ class TestGzip(BaseTest): isizeBytes = fRead.read(4) self.assertEqual(isizeBytes, struct.pack('