python / python/cpython

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

Abierto
#133,998 7 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

3.15 3.16 stdlib type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza en Lib/gzip.py, en _write_gzip_header, y reproduce el ejemplo proporcionado de GzipFile con un mtime fuera del rango de 32 bits. Revisa los PRs enlazados antes de trabajar, ya que indican que este problema podría estar ya resuelto. Se considera terminado cuando el archivo gzip se crea con MTIME establecido en 0 en lugar de generar struct.error.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
backend
Tipo de issue
Error
Dificultad
2/5
Tiempo estimado
1-3 horas
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
30/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.