~ubuntu-branches/ubuntu/karmic/python3.0/karmic

« back to all changes in this revision

Viewing changes to Lib/zipfile.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-16 17:18:23 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090216171823-1d5cm5qnnjvmnzzm
Tags: 3.0.1-0ubuntu1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
XXX references to utf-8 need further investigation.
5
5
"""
6
6
import struct, os, time, sys, shutil
7
 
import binascii, io
 
7
import binascii, io, stat
8
8
 
9
9
try:
10
10
    import zlib # We may need its compression method
28
28
 
29
29
error = BadZipfile      # The exception raised by this module
30
30
 
31
 
ZIP64_LIMIT= (1 << 31) - 1
 
31
ZIP64_LIMIT = (1 << 31) - 1
32
32
ZIP_FILECOUNT_LIMIT = 1 << 16
33
33
ZIP_MAX_COMMENT = (1 << 16) - 1
34
34
 
198
198
        # Append a blank comment and record start offset
199
199
        endrec.append(b"")
200
200
        endrec.append(filesize - sizeEndCentDir)
201
 
        if endrec[_ECD_OFFSET] == 0xffffffff:
202
 
            # the value for the "offset of the start of the central directory"
203
 
            # indicates that there is a "Zip64 end of central directory"
204
 
            # structure present, so go look for it
205
 
            return _EndRecData64(fpin, -sizeEndCentDir, endrec)
206
201
 
207
 
        return endrec
 
202
        # Try to read the "Zip64 end of central directory" structure
 
203
        return _EndRecData64(fpin, -sizeEndCentDir, endrec)
208
204
 
209
205
    # Either this is not a ZIP file, or it is a ZIP file with an archive
210
206
    # comment.  Search the end of the file for the "end of central directory"
225
221
            # Append the archive comment and start offset
226
222
            endrec.append(comment)
227
223
            endrec.append(maxCommentStart + start)
228
 
            if endrec[_ECD_OFFSET] == 0xffffffff:
229
 
                # There is apparently a "Zip64 end of central directory"
230
 
                # structure present, so go look for it
231
 
                return _EndRecData64(fpin, start - filesize, endrec)
232
 
            return endrec
 
224
 
 
225
            # Try to read the "Zip64 end of central directory" structure
 
226
            return _EndRecData64(fpin, maxCommentStart + start - filesize,
 
227
                                 endrec)
233
228
 
234
229
    # Unable to find a valid end of central directory structure
235
230
    return
952
947
        """
953
948
        # build the destination pathname, replacing
954
949
        # forward slashes to platform specific separators.
955
 
        if targetpath[-1:] == "/":
 
950
        if targetpath[-1:] in (os.path.sep, os.path.altsep):
956
951
            targetpath = targetpath[:-1]
957
952
 
958
953
        # don't include leading "/" from file name if present
959
 
        if os.path.isabs(member.filename):
 
954
        if member.filename[0] == '/':
960
955
            targetpath = os.path.join(targetpath, member.filename[1:])
961
956
        else:
962
957
            targetpath = os.path.join(targetpath, member.filename)
968
963
        if upperdirs and not os.path.exists(upperdirs):
969
964
            os.makedirs(upperdirs)
970
965
 
 
966
        if member.filename[-1] == '/':
 
967
            os.mkdir(targetpath)
 
968
            return targetpath
 
969
 
971
970
        source = self.open(member, pwd=pwd)
972
971
        target = open(targetpath, "wb")
973
972
        shutil.copyfileobj(source, target)
1007
1006
                  "Attempt to write to ZIP archive that was already closed")
1008
1007
 
1009
1008
        st = os.stat(filename)
 
1009
        isdir = stat.S_ISDIR(st.st_mode)
1010
1010
        mtime = time.localtime(st.st_mtime)
1011
1011
        date_time = mtime[0:6]
1012
1012
        # Create ZipInfo instance to store file information
1015
1015
        arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
1016
1016
        while arcname[0] in (os.sep, os.altsep):
1017
1017
            arcname = arcname[1:]
 
1018
        if isdir:
 
1019
            arcname += '/'
1018
1020
        zinfo = ZipInfo(arcname, date_time)
1019
1021
        zinfo.external_attr = (st[0] & 0xFFFF) << 16      # Unix attributes
1020
1022
        if compress_type is None:
1028
1030
 
1029
1031
        self._writecheck(zinfo)
1030
1032
        self._didModify = True
 
1033
 
 
1034
        if isdir:
 
1035
            zinfo.file_size = 0
 
1036
            zinfo.compress_size = 0
 
1037
            zinfo.CRC = 0
 
1038
            self.filelist.append(zinfo)
 
1039
            self.NameToInfo[zinfo.filename] = zinfo
 
1040
            self.fp.write(zinfo.FileHeader())
 
1041
            return
 
1042
 
1031
1043
        fp = io.open(filename, "rb")
1032
1044
        # Must overwrite CRC and sizes with correct data later
1033
1045
        zinfo.CRC = CRC = 0
1186
1198
 
1187
1199
            pos2 = self.fp.tell()
1188
1200
            # Write end-of-zip-archive record
 
1201
            centDirCount = count
 
1202
            centDirSize = pos2 - pos1
1189
1203
            centDirOffset = pos1
1190
 
            if pos1 > ZIP64_LIMIT:
 
1204
            if (centDirCount >= ZIP_FILECOUNT_LIMIT or
 
1205
                centDirOffset > ZIP64_LIMIT or
 
1206
                centDirSize > ZIP64_LIMIT):
1191
1207
                # Need to write the ZIP64 end-of-archive records
1192
1208
                zip64endrec = struct.pack(
1193
1209
                        structEndArchive64, stringEndArchive64,
1194
 
                        44, 45, 45, 0, 0, count, count, pos2 - pos1, pos1)
 
1210
                        44, 45, 45, 0, 0, centDirCount, centDirCount,
 
1211
                        centDirSize, centDirOffset)
1195
1212
                self.fp.write(zip64endrec)
1196
1213
 
1197
1214
                zip64locrec = struct.pack(
1198
1215
                        structEndArchive64Locator,
1199
1216
                        stringEndArchive64Locator, 0, pos2, 1)
1200
1217
                self.fp.write(zip64locrec)
1201
 
                centDirOffset = 0xFFFFFFFF
 
1218
                centDirCount = min(centDirCount, 0xFFFF)
 
1219
                centDirSize = min(centDirSize, 0xFFFFFFFF)
 
1220
                centDirOffset = min(centDirOffset, 0xFFFFFFFF)
1202
1221
 
1203
1222
            # check for valid comment length
1204
1223
            if len(self.comment) >= ZIP_MAX_COMMENT:
1208
1227
                self.comment = self.comment[:ZIP_MAX_COMMENT]
1209
1228
 
1210
1229
            endrec = struct.pack(structEndArchive, stringEndArchive,
1211
 
                                 0, 0, count % ZIP_FILECOUNT_LIMIT,
1212
 
                                 count % ZIP_FILECOUNT_LIMIT, pos2 - pos1,
1213
 
                                 centDirOffset, len(self.comment))
 
1230
                                 0, 0, centDirCount, centDirCount,
 
1231
                                 centDirSize, centDirOffset, len(self.comment))
1214
1232
            self.fp.write(endrec)
1215
1233
            self.fp.write(self.comment)
1216
1234
            self.fp.flush()