Skip to content

Commit

Permalink
zipfile: Support for extended_*time attributes
Browse files Browse the repository at this point in the history
zipinfo now supports attributes like extended_atime,
extended_ctime, extended_mtime

Signed-off-by: Abhijeet Kasurde <[email protected]>
  • Loading branch information
Akasurde committed Jun 26, 2024
1 parent 7fb32e0 commit 121d4c5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
17 changes: 17 additions & 0 deletions Doc/library/zipfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,23 @@ Instances have the following methods and attributes:

Size of the uncompressed file.

.. attribute:: ZipInfo.extended_mtime

Extended modified timestamp of the uncompressed file.

.. versionadded:: 3.14

.. attribute:: ZipInfo.extended_atime

Extended access timestamp of the uncompressed file.

.. versionadded:: 3.14

.. attribute:: ZipInfo.extended_ctime

Extended changed timestamp of the uncompressed file.

.. versionadded:: 3.14

.. _zipfile-commandline:
.. program:: zipfile
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_zipfile/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2227,6 +2227,10 @@ def test_create_empty_zipinfo_default_attributes(self):
self.assertEqual(zi.file_size, 0)
self.assertEqual(zi.compress_size, 0)

self.assertEqual(zi.extended_mtime, None)
self.assertEqual(zi.extended_atime, None)
self.assertEqual(zi.extended_ctime, None)

def test_zipfile_with_short_extra_field(self):
"""If an extra field in the header is less than 4 bytes, skip it."""
zipdata = (
Expand Down
14 changes: 14 additions & 0 deletions Lib/zipfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ class ZipInfo:
'file_size',
'_raw_time',
'_end_offset',
'extended_mtime',
'extended_atime',
'extended_ctime',
)

def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
Expand Down Expand Up @@ -431,6 +434,9 @@ def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
self.compress_size = 0 # Size of the compressed file
self.file_size = 0 # Size of the uncompressed file
self._end_offset = None # Start of the next local header or central directory
self.extended_mtime = None # Extended access timestamp
self.extended_atime = None # Extended modified timestamp
self.extended_ctime = None # Extended changed timestamp
# Other attributes are set by class ZipFile:
# header_offset Byte offset to the file header
# CRC CRC-32 of the uncompressed file
Expand Down Expand Up @@ -563,6 +569,14 @@ def _decodeExtra(self, filename_crc):
except UnicodeDecodeError as e:
raise BadZipFile('Corrupt unicode path extra field (0x7075): invalid utf-8 bytes') from e

elif tp == 0x5455:
flags = extra[4]
if flags & 0x1 and ln >= 5:
self.extended_mtime = int.from_bytes(extra[5:9], "little")
if flags & 0x2 and ln >= 9:
self.extended_atime = int.from_bytes(extra[9:13], "little")
if flags & 0x4 and ln >= 13:
self.extended_ctime = int.from_bytes(extra[13:17], "little")
extra = extra[ln+4:]

@classmethod
Expand Down

0 comments on commit 121d4c5

Please sign in to comment.