python / python/cpython

zipinfo: strict_timestamps=False fails in combination with SOURCE_DATE_EPOCH

Ouverte
#152,445 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

stdlib type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug report

Bug description:

I have a python program which (among other things) adds a text file to a ZIP with the following code:

zf = zipfile.ZipFile(filename, "a")
zf.writestr("test.txt", "Hello World")
zf.close()

In Python 3.13 and below this worked fine. In Python 3.14 I received a bug report from a NixOS user. For some reason, some tool in their environment had set SOURCE_DATE_EPOCH to a low value between 0 (1970) and 315529200 (1980).

Since Python 3.14, when adding a file to a ZIP, Python honors that variable (so this bug seems to be directly caused by #124435 ). This caused it to fail to add the text file to the ZIP because it tried to use that date for the file's modification date which ZIP doesn't support:

  File "/uv/python/cpython-3.14.4-linux-x86_64-gnu/lib/python3.14/zipfile/__init__.py", line 561, in FileHeader
    header = struct.pack(structFileHeader, stringFileHeader,
                         self.extract_version, self.reserved, flag_bits,
                         self.compress_type, dostime, dosdate, CRC,
                         compress_size, file_size,
                         len(filename), len(extra))
struct.error: 'H' format requires 0 <= number <= 65535

Then I thought, okay, maybe that's a bug in my script, and I added strict_timestamps=False. According to the documentation, that should make it so that dates before 1980 are set to 1980, and dates after 2107 are set to 2107.

Perfect - or so I thought.

Apparently, that only works if I add an file whose actual file system timestamp is before 1980 (as the timestamp is manipulated in the from_file function). When I add a file to the ZIP using writestr, and the timestamp comes from SOURCE_DATE_EPOCH, and it refers to a date before 1980, the timestamp doesn't get updated to 1980 and it just fails to add the given file.

Same issue also appears, by the way, if the actual system time is set to some date in the 1970s. It doesn't set the time to 1980, it just tries to add the file with the current time of 1970 and then fails.

That looks like a bug to me - if I set strict_timestamps=False, I have set SOURCE_DATE_EPOCH (or my system time) to a time before 1980 and I then add a file to the ZIP using writestr, I'd expect it to set the timestamp to 1980, not just throw an exception.

CPython versions tested on:

3.14 and 3.15

Operating systems tested on:

Linux

Linked PRs
  • gh-152452

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans zipfile/init.py autour de FileHeader et suivez le chemin de l’horodatage de writestr, en le comparant à la gestion de strict_timestamps par from_file. La modification est terminée lorsque strict_timestamps=False ramène à 1980 les horodatages antérieurs à 1980 provenant de SOURCE_DATE_EPOCH ou de l’horloge système, au lieu de déclencher le struct.error indiqué ; consultez gh-152452, car l’issue renvoie vers un pull request.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
backend
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.