From b1f707eebf8696103d1db4b00e75cb66e68d6fb5 Mon Sep 17 00:00:00 2001 From: William Chargin Date: Mon, 20 Jan 2020 00:43:53 -0800 Subject: [PATCH 1/2] bpo-39389: gzip: fix compression level metadata 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. Test Plan: Unit tests added; they fail before this patch (in 2 of 3 cases) and pass after it. wchargin-branch: gzip-compresslevel-metadata --- Lib/gzip.py | 12 +++++++++--- Lib/test/test_gzip.py | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Lib/gzip.py b/Lib/gzip.py index e60d8ad5995b3a..e422773b3edfb7 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -209,7 +209,7 @@ def __init__(self, filename=None, mode=None, self.fileobj = fileobj if self.mode == WRITE: - self._write_gzip_header() + self._write_gzip_header(compresslevel) @property def filename(self): @@ -236,7 +236,7 @@ def _init_write(self, filename): 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: @@ -257,7 +257,13 @@ def _write_gzip_header(self): 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 57d851cf9cf156..78334213f24b1a 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -358,6 +358,26 @@ def test_metadata(self): isizeBytes = fRead.read(4) self.assertEqual(isizeBytes, struct.pack(' Date: Mon, 20 Jan 2020 00:56:27 -0800 Subject: [PATCH 2/2] Add news entry wchargin-branch: gzip-compresslevel-metadata --- .../next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst diff --git a/Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst b/Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst new file mode 100644 index 00000000000000..d4c80506f7d6bb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-20-00-56-01.bpo-39389.fEirIS.rst @@ -0,0 +1,2 @@ +Write accurate compression level metadata in :mod:`gzip` archives, rather +than always signaling maximum compression.