python / python/cpython

gzip: cannot create file if mtime > `2106-02-07T06:28:15`

Offen
#133,998 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

3.15 3.16 stdlib type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug report

Bug description:

We had a VM where ntp went very wonky and ended up thinking it was the year 2141!
Trying to write a gzip file with the system clock greater than 2106-02-07T06:28:15 results in a struct error because we tried to cram a 64-bit int into a 32 bit field (which won't work).

I wouldn't expect the gzip module to explode in this case, I'd expect it to set the MTIME to 0.
RFC 1952 (if that's at all relevant these days) states

MTIME = 0 means no time stamp is available

MWE

Only tested this on macOS on 3.13.2, but from a cursory glance, the mtime handling hasn't changed in over a decade.

>>> import gzip
>>> gzip.GzipFile("/dev/null", "w", mtime=2**32+1)
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    gzip.GzipFile("/dev/null", "w", mtime=2**32+1)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/gzip.py", line 237, in __init__
    self._write_gzip_header(compresslevel)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/gzip.py", line 281, in _write_gzip_header
    write32u(self.fileobj, int(mtime))
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/gzip.py", line 77, in write32u
    output.write(struct.pack("<L", value))
                 ~~~~~~~~~~~^^^^^^^^^^^^^
struct.error: 'L' format requires 0 <= number <= 4294967295
Proposed Patch

I'd naïvely fix it with this patch

diff --git a/Lib/gzip.py b/Lib/gzip.py
index c00f51858de..29345de4659 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -297,6 +297,8 @@ def _write_gzip_header(self, compresslevel):
         mtime = self._write_mtime
         if mtime is None:
             mtime = time.time()
+        if mtime > 4294967295:
+            mtime = 0
         write32u(self.fileobj, int(mtime))
         if compresslevel == _COMPRESS_LEVEL_BEST:
             xfl = b'\002'
CPython versions tested on:

3.13

Operating systems tested on:

macOS

Linked PRs
  • gh-134278
  • gh-150221
  • gh-151828

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne in Lib/gzip.py bei _write_gzip_header und reproduziere das bereitgestellte GzipFile-Beispiel mit einem mtime außerhalb des 32-Bit-Bereichs. Prüfe die verlinkten PRs, bevor du daran arbeitest, da sie darauf hindeuten, dass dieses Problem möglicherweise bereits behoben ist. Als erledigt gilt die Aufgabe, wenn die gzip-Datei mit auf 0 gesetztem MTIME erstellt wird, anstatt struct.error auszulösen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
30/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.