Mark extracted files as executable

Python's zipfile doens't restore file permission by default, so we need
to manually restore permission.

Test: th
Bug: 290643514
Change-Id: I89c1e2ee178b534fa7e3f02afd04d170100d37e7
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 39e1bdd..bd56ca6 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -2120,20 +2120,33 @@
   # According to https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/6297838#6297838
   # higher bits of |external_attr| are unix file permission and types
   unix_filetype = info.external_attr >> 16
+  file_perm = unix_filetype & 0o777
 
   def CheckMask(a, mask):
     return (a & mask) == mask
 
   def IsSymlink(a):
     return CheckMask(a, stat.S_IFLNK)
+
+  def IsDir(a):
+    return CheckMask(a, stat.S_IFDIR)
   # python3.11 zipfile implementation doesn't handle symlink correctly
   if not IsSymlink(unix_filetype):
-    return input_zip.extract(info, dirname)
+    target = input_zip.extract(info, dirname)
+    # We want to ensure that the file is at least read/writable by owner and readable by all users
+    if IsDir(unix_filetype):
+      os.chmod(target, file_perm | 0o755)
+    else:
+      os.chmod(target, file_perm | 0o644)
+    return target
   if dirname is None:
     dirname = os.getcwd()
   target = os.path.join(dirname, info.filename)
   os.makedirs(os.path.dirname(target), exist_ok=True)
+  if os.path.exists(target):
+    os.unlink(target)
   os.symlink(input_zip.read(info).decode(), target)
+  return target
 
 
 def UnzipToDir(filename, dirname, patterns=None):