tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

validate_static_library_dex_references.py (3158B)


      1 #!/usr/bin/env python3
      2 # Copyright 2019 The Chromium Authors
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 import argparse
      7 import os
      8 import re
      9 import sys
     10 import zipfile
     11 
     12 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
     13 from pylib.dex import dex_parser
     14 from util import build_utils
     15 import action_helpers  # build_utils adds //build to sys.path.
     16 
     17 _FLAGS_PATH = (
     18    '//chrome/android/java/static_library_dex_reference_workarounds.flags')
     19 
     20 
     21 def _FindIllegalStaticLibraryReferences(static_lib_dex_files,
     22                                        main_apk_dex_files):
     23  main_apk_defined_types = set()
     24  for dex_file in main_apk_dex_files:
     25    for class_def_item in dex_file.class_def_item_list:
     26      main_apk_defined_types.add(
     27          dex_file.GetTypeString(class_def_item.class_idx))
     28 
     29  static_lib_referenced_types = set()
     30  for dex_file in static_lib_dex_files:
     31    for type_item in dex_file.type_item_list:
     32      static_lib_referenced_types.add(
     33          dex_file.GetString(type_item.descriptor_idx))
     34 
     35  return main_apk_defined_types.intersection(static_lib_referenced_types)
     36 
     37 
     38 def _DexFilesFromPath(path):
     39  if zipfile.is_zipfile(path):
     40    with zipfile.ZipFile(path) as z:
     41      return [
     42          dex_parser.DexFile(bytearray(z.read(name))) for name in z.namelist()
     43          if re.match(r'.*classes[0-9]*\.dex$', name)
     44      ]
     45  else:
     46    with open(path) as f:
     47      return dex_parser.DexFile(bytearray(f.read()))
     48 
     49 
     50 def main(args):
     51  args = build_utils.ExpandFileArgs(args)
     52  parser = argparse.ArgumentParser()
     53  action_helpers.add_depfile_arg(parser)
     54  parser.add_argument(
     55      '--stamp', required=True, help='Path to file to touch upon success.')
     56  parser.add_argument(
     57      '--static-library-dex',
     58      required=True,
     59      help='classes.dex or classes.zip for the static library APK that was '
     60      'proguarded with other dependent APKs')
     61  parser.add_argument(
     62      '--static-library-dependent-dex',
     63      required=True,
     64      action='append',
     65      dest='static_library_dependent_dexes',
     66      help='classes.dex or classes.zip for the APKs that use the static '
     67      'library APK')
     68  args = parser.parse_args(args)
     69 
     70  static_library_dexfiles = _DexFilesFromPath(args.static_library_dex)
     71  for path in args.static_library_dependent_dexes:
     72    dependent_dexfiles = _DexFilesFromPath(path)
     73    illegal_references = _FindIllegalStaticLibraryReferences(
     74        static_library_dexfiles, dependent_dexfiles)
     75 
     76    if illegal_references:
     77      msg = 'Found illegal references from {} to {}\n'.format(
     78          args.static_library_dex, path)
     79      msg += 'Add a -keep rule to avoid this. '
     80      msg += 'See {} for an example and why this is necessary.\n'.format(
     81          _FLAGS_PATH)
     82      msg += 'The illegal references are:\n'
     83      msg += '\n'.join(illegal_references)
     84      sys.stderr.write(msg)
     85      sys.exit(1)
     86 
     87  input_paths = [args.static_library_dex] + args.static_library_dependent_dexes
     88  build_utils.Touch(args.stamp)
     89  action_helpers.write_depfile(args.depfile, args.stamp, inputs=input_paths)
     90 
     91 
     92 if __name__ == '__main__':
     93  sys.exit(main(sys.argv[1:]))