Skip to content

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

Description

@huwcbjones

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

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on May 14, 2025
  2. StanFromIreland commented on May 14, 2025

    @StanFromIreland
    Member

    It is consistent with the specification, I am +1 for setting it to 0. This will have to be documented.

  3. added a commit that references this issue on May 19, 2025
  4. adang1345 commented on May 19, 2025

    @adang1345
    Contributor

    I'm at the PyCon US sprints right now, and I decided to give this issue a shot. I have made a pull request.

  5. StanFromIreland commented on May 19, 2025

    @StanFromIreland
    Member

    @adang1345 In the future please ask before using someones idea, they may want to open the pr themselves.

  6. huwcbjones commented on May 20, 2025

    @huwcbjones
    Author

    @adang1345 , in this case I'd be 108 before this issue could cause any noticeable problems.
    Whether I make it that far or not, I think my care levels would be quite low, so feel free to fix this!

  7. serhiy-storchaka commented on May 31, 2025

    @serhiy-storchaka
    Member

    From the changelog for the GNU gzip 1.9 (2018-01-07):

    When converting from system-dependent time_t format to the 32-bit
    unsigned MTIME format used in gzip files, if a timestamp does not
    fit gzip now substitutes zero instead of the timestamp's low-order
    32 bits, as per Internet RFC 1952. When converting from MTIME to
    time_t format, if a timestamp does not fit gzip now warns and
    substitutes the nearest in-range value instead of crashing or
    silently substituting an implementation-defined value (typically,
    the timestamp's low-order bits). This affects timestamps before
    1970 and after 2106, and timestamps after 2038 on platforms with
    32-bit signed time_t. [bug present since the beginning]

    So replacing the mtime outside of the valid range with 0 looks the most preferable solution.

  8. added a commit that references this issue on May 22, 2026
  9. serhiy-storchaka commented on May 22, 2026

    @serhiy-storchaka
    Member

    There is also a similar issue in tarfile (see _init_write_gz). @adang1345, are you interesting to fix it there?

  10. added
    3.15pre-release feature fixes, bugs and security fixes
    3.16new features, bugs and security fixes
    on May 22, 2026
  11. added a commit that references this issue on May 22, 2026
  12. added 2 commits that reference this issue on May 22, 2026
  13. harjothkhara commented on Aug 4, 2026

    @harjothkhara
    Contributor

    Hi, PR gh-151828 handles the tarfile _init_write_gz case Serhiy flagged above. Can someone please take a look when you have time?

  14. added a commit that references this issue on Oct 5, 2026
  15. added a commit that references this issue on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.15pre-release feature fixes, bugs and security fixes3.16new features, bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions