diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2009-01-24 14:00:33 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2009-01-24 14:00:33 (GMT) |
commit | 0dfcfc8b59610422def8ec49d2319ec51380e9fa (patch) | |
tree | fa998019852e76033d710bf901fc5586b5fcaa4c /Lib/zipfile.py | |
parent | 89e759d462ac9bb3463f5ff7a3f8e123af380edb (diff) | |
download | cpython-0dfcfc8b59610422def8ec49d2319ec51380e9fa.zip cpython-0dfcfc8b59610422def8ec49d2319ec51380e9fa.tar.gz cpython-0dfcfc8b59610422def8ec49d2319ec51380e9fa.tar.bz2 |
Issue #4710: Extract directories properly in the zipfile module;
allow adding directories to a zipfile.
Diffstat (limited to 'Lib/zipfile.py')
-rw-r--r-- | Lib/zipfile.py | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/Lib/zipfile.py b/Lib/zipfile.py index eae9d1f..3106353 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -2,7 +2,7 @@ Read and write ZIP files. """ import struct, os, time, sys, shutil -import binascii, cStringIO +import binascii, cStringIO, stat try: import zlib # We may need its compression method @@ -952,11 +952,11 @@ class ZipFile: """ # build the destination pathname, replacing # forward slashes to platform specific separators. - if targetpath[-1:] == "/": + if targetpath[-1:] in (os.path.sep, os.path.altsep): targetpath = targetpath[:-1] # don't include leading "/" from file name if present - if os.path.isabs(member.filename): + if member.filename[0] == '/': targetpath = os.path.join(targetpath, member.filename[1:]) else: targetpath = os.path.join(targetpath, member.filename) @@ -968,6 +968,10 @@ class ZipFile: if upperdirs and not os.path.exists(upperdirs): os.makedirs(upperdirs) + if member.filename[-1] == '/': + os.mkdir(targetpath) + return targetpath + source = self.open(member, pwd=pwd) target = file(targetpath, "wb") shutil.copyfileobj(source, target) @@ -1007,6 +1011,7 @@ class ZipFile: "Attempt to write to ZIP archive that was already closed") st = os.stat(filename) + isdir = stat.S_ISDIR(st.st_mode) mtime = time.localtime(st.st_mtime) date_time = mtime[0:6] # Create ZipInfo instance to store file information @@ -1015,6 +1020,8 @@ class ZipFile: arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) while arcname[0] in (os.sep, os.altsep): arcname = arcname[1:] + if isdir: + arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes if compress_type is None: @@ -1028,6 +1035,16 @@ class ZipFile: self._writecheck(zinfo) self._didModify = True + + if isdir: + zinfo.file_size = 0 + zinfo.compress_size = 0 + zinfo.CRC = 0 + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + self.fp.write(zinfo.FileHeader()) + return + fp = open(filename, "rb") # Must overwrite CRC and sizes with correct data later zinfo.CRC = CRC = 0 |