Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcec9d0e authored by Tao Bao's avatar Tao Bao Committed by Android Git Automerger
Browse files

am 44158945: Merge "Wrap zipfile.write(), writestr() and close()"

* commit '44158945':
  Wrap zipfile.write(), writestr() and close()
parents 42d4401a 44158945
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -33,10 +33,6 @@ import os
import tempfile
import zipfile

# missing in Python 2.4 and before
if not hasattr(os, "SEEK_SET"):
  os.SEEK_SET = 0

import build_image
import common

@@ -189,7 +185,7 @@ def AddUserdata(output_zip, prefix="IMAGES/"):
  assert succ, "build userdata.img image failed"

  common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
  output_zip.write(img.name, prefix + "userdata.img")
  common.ZipWrite(output_zip, img.name, prefix + "userdata.img")
  img.close()
  os.rmdir(user_dir)
  os.rmdir(temp_dir)
@@ -226,7 +222,7 @@ def AddCache(output_zip, prefix="IMAGES/"):
  assert succ, "build cache.img image failed"

  common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
  output_zip.write(img.name, prefix + "cache.img")
  common.ZipWrite(output_zip, img.name, prefix + "cache.img")
  img.close()
  os.rmdir(user_dir)
  os.rmdir(temp_dir)
@@ -252,7 +248,7 @@ def AddImagesToTargetFiles(filename):
    OPTIONS.info_dict["selinux_fc"] = os.path.join(
        OPTIONS.input_tmp, "BOOT", "RAMDISK", "file_contexts")

  input_zip.close()
  common.ZipClose(input_zip)
  output_zip = zipfile.ZipFile(filename, "a",
                               compression=zipfile.ZIP_DEFLATED)

@@ -297,7 +293,7 @@ def AddImagesToTargetFiles(filename):
  banner("cache")
  AddCache(output_zip)

  output_zip.close()
  common.ZipClose(output_zip)

def main(argv):
  def option_handler(o, _):
+4 −4
Original line number Diff line number Diff line
@@ -205,8 +205,8 @@ def BuildImage(in_dir, prop_dict, out_file):
  Returns:
    True iff the image is built successfully.
  """
  # system_root_image=true: build a system.img that combines the contents of /system
  # and the ramdisk, and can be mounted at the root of the file system.
  # system_root_image=true: build a system.img that combines the contents of
  # /system and the ramdisk, and can be mounted at the root of the file system.
  origin_in = in_dir
  fs_config = prop_dict.get("fs_config")
  if (prop_dict.get("system_root_image") == "true"
+46 −11
Original line number Diff line number Diff line
@@ -32,10 +32,7 @@ import zipfile
import blockimgdiff
import rangelib

try:
from hashlib import sha1 as sha1
except ImportError:
  from sha import sha as sha1


class Options(object):
@@ -380,6 +377,10 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
    p.communicate()
    assert p.returncode == 0, "vboot_signer of %s image failed" % path

    # Clean up the temp files.
    img_unsigned.close()
    img_keyblock.close()

  img.seek(os.SEEK_SET, 0)
  data = img.read()

@@ -854,16 +855,50 @@ def ZipWrite(zip_file, filename, arcname=None, perms=0o644,
    zipfile.ZIP64_LIMIT = saved_zip64_limit


def ZipWriteStr(zip_file, filename, data, perms=0o644, compression=None):
  # use a fixed timestamp so the output is repeatable.
  zinfo = zipfile.ZipInfo(filename=filename,
                          date_time=(2009, 1, 1, 0, 0, 0))
  if compression is None:
def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=0o644,
                compress_type=None):
  """Wrap zipfile.writestr() function to work around the zip64 limit.

  Even with the ZIP64_LIMIT workaround, it won't allow writing a string
  longer than 2GiB. It gives 'OverflowError: size does not fit in an int'
  when calling crc32(bytes).

  But it still works fine to write a shorter string into a large zip file.
  We should use ZipWrite() whenever possible, and only use ZipWriteStr()
  when we know the string won't be too long.
  """

  saved_zip64_limit = zipfile.ZIP64_LIMIT
  zipfile.ZIP64_LIMIT = (1 << 32) - 1

  if not isinstance(zinfo_or_arcname, zipfile.ZipInfo):
    zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname)
    zinfo.compress_type = zip_file.compression
  else:
    zinfo.compress_type = compression
    zinfo = zinfo_or_arcname

  # If compress_type is given, it overrides the value in zinfo.
  if compress_type is not None:
    zinfo.compress_type = compress_type

  # Use a fixed timestamp so the output is repeatable.
  zinfo.external_attr = perms << 16
  zinfo.date_time = (2009, 1, 1, 0, 0, 0)

  zip_file.writestr(zinfo, data)
  zipfile.ZIP64_LIMIT = saved_zip64_limit


def ZipClose(zip_file):
  # http://b/18015246
  # zipfile also refers to ZIP64_LIMIT during close() when it writes out the
  # central directory.
  saved_zip64_limit = zipfile.ZIP64_LIMIT
  zipfile.ZIP64_LIMIT = (1 << 32) - 1

  zip_file.close()

  zipfile.ZIP64_LIMIT = saved_zip64_limit


class DeviceSpecificParams(object):
@@ -969,7 +1004,7 @@ class File(object):
    return t

  def AddToZip(self, z, compression=None):
    ZipWriteStr(z, self.name, self.data, compression=compression)
    ZipWriteStr(z, self.name, self.data, compress_type=compression)

DIFF_PROGRAM_BY_EXT = {
    ".gz" : "imgdiff",
+4 −9
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ OPTIONS = common.OPTIONS

def CopyInfo(output_zip):
  """Copy the android-info.txt file from the input to the output."""
  output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
  common.ZipWrite(
      output_zip, os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
      "android-info.txt")


@@ -133,13 +134,7 @@ def main(argv):

  finally:
    print "cleaning up..."
    # http://b/18015246
    # See common.py for context.  zipfile also refers to ZIP64_LIMIT during
    # close() when it writes out the central directory.
    saved_zip64_limit = zipfile.ZIP64_LIMIT
    zipfile.ZIP64_LIMIT = (1 << 32) - 1
    output_zip.close()
    zipfile.ZIP64_LIMIT = saved_zip64_limit
    common.ZipClose(output_zip)
    shutil.rmtree(OPTIONS.input_tmp)

  print "done."
+5 −5
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ if sys.hexversion < 0x02070000:
  print >> sys.stderr, "Python 2.7 or newer is required."
  sys.exit(1)

import copy
import multiprocessing
import os
import tempfile
@@ -371,6 +370,7 @@ def CopyPartitionFiles(itemset, input_zip, output_zip=None, substitute=None):
        symlinks.append((input_zip.read(info.filename),
                         "/" + partition + "/" + basefilename))
      else:
        import copy
        info2 = copy.copy(info)
        fn = info2.filename = partition + "/" + basefilename
        if substitute and fn in substitute and substitute[fn] is None:
@@ -380,7 +380,7 @@ def CopyPartitionFiles(itemset, input_zip, output_zip=None, substitute=None):
            data = substitute[fn]
          else:
            data = input_zip.read(info.filename)
          output_zip.writestr(info2, data)
          common.ZipWriteStr(output_zip, info2, data)
        if fn.endswith("/"):
          itemset.Get(fn[:-1], is_dir=True)
        else:
@@ -1581,6 +1581,7 @@ def main(argv):
        OPTIONS.package_key = OPTIONS.info_dict.get(
            "default_system_dev_certificate",
            "build/target/product/security/testkey")
      common.ZipClose(output_zip)
      break

    else:
@@ -1601,15 +1602,14 @@ def main(argv):
        common.DumpInfoDict(OPTIONS.source_info_dict)
      try:
        WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
        common.ZipClose(output_zip)
        break
      except ValueError:
        if not OPTIONS.fallback_to_full:
          raise
        print "--- failed to build incremental; falling back to full ---"
        OPTIONS.incremental_source = None
        output_zip.close()

  output_zip.close()
        common.ZipClose(output_zip)

  if not OPTIONS.no_signing:
    SignOutput(temp_zip_file.name, args[1])
Loading