|  | #!/usr/bin/env python3 | 
|  | # Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file | 
|  | # for details. All rights reserved. Use of this source code is governed by a | 
|  | # BSD-style license that can be found in the LICENSE file. | 
|  | from __future__ import print_function | 
|  | import os | 
|  | import sys | 
|  | import zipfile | 
|  |  | 
|  | # Proguard lookup program classes before library classes. In R8 this is | 
|  | # not the behaviour (it used to be) R8 will check library classes before | 
|  | # program classes. Some apps have duplicate classes in the library and program. | 
|  | # To make these apps work with R8 simulate program classes before library | 
|  | # classes by creating a new library jar which have all the provided library | 
|  | # classes which are not also in program classes. | 
|  | def SanitizeLibrariesInPgconf( | 
|  | sanitized_lib_path, | 
|  | sanitized_pgconf_path, | 
|  | pgconfs, | 
|  | injars = None, | 
|  | libraryjars = None): | 
|  | with open(sanitized_pgconf_path, 'w') as sanitized_pgconf: | 
|  | injars = [] if injars is None else injars | 
|  | libraryjars = [] if libraryjars is None else libraryjars | 
|  | for pgconf in pgconfs: | 
|  | pgconf_dirname = os.path.abspath(os.path.dirname(pgconf)) | 
|  | first_library_jar = True | 
|  | with open(pgconf) as pgconf_file: | 
|  | for line in pgconf_file: | 
|  | trimmed = line.strip() | 
|  | if trimmed.startswith('-injars'): | 
|  | # Collect -injars and leave them in the configuration. | 
|  | injar = os.path.join( | 
|  | pgconf_dirname, trimmed[len('-injars'):].strip()) | 
|  | injars.append(injar) | 
|  | sanitized_pgconf.write('-injars {}\n'.format(injar)) | 
|  | elif trimmed.startswith('-libraryjars'): | 
|  | # Collect -libraryjars and replace them with the sanitized library. | 
|  | libraryjar = os.path.join( | 
|  | pgconf_dirname, trimmed[len('-libraryjars'):].strip()) | 
|  | libraryjars.append(libraryjar) | 
|  | if first_library_jar: | 
|  | sanitized_pgconf.write( | 
|  | '-libraryjars {}\n'.format(sanitized_lib_path)) | 
|  | first_library_jar = False | 
|  | sanitized_pgconf.write('# {}'.format(line)) | 
|  | else: | 
|  | sanitized_pgconf.write(line) | 
|  |  | 
|  | SanitizeLibraries(sanitized_lib_path, libraryjars, injars) | 
|  |  | 
|  |  | 
|  | def SanitizeLibraries(sanitized_lib_path, libraryjars, injars): | 
|  | program_entries = set() | 
|  | library_entries = set() | 
|  |  | 
|  | for injar in injars: | 
|  | with zipfile.ZipFile(injar, 'r') as injar_zf: | 
|  | for zipinfo in injar_zf.infolist(): | 
|  | program_entries.add(zipinfo.filename) | 
|  |  | 
|  | with zipfile.ZipFile(sanitized_lib_path, 'w') as output_zf: | 
|  | for libraryjar in libraryjars: | 
|  | with zipfile.ZipFile(libraryjar, 'r') as input_zf: | 
|  | for zipinfo in input_zf.infolist(): | 
|  | if (not zipinfo.filename in program_entries | 
|  | and not zipinfo.filename in library_entries): | 
|  | library_entries.add(zipinfo.filename) | 
|  | output_zf.writestr(zipinfo, input_zf.read(zipinfo)) | 
|  |  | 
|  |  | 
|  | def usage(argv, error): | 
|  | print(error) | 
|  | print("Usage: sanitize_libraries.py <sanitized_lib> <sanitized_pgconf> (" | 
|  | + "--injar <existing_injar>" | 
|  | + "|--libraryjar <existing_library_jar>" | 
|  | + "|--pgconf <existing_pgconf>)+") | 
|  | return 1 | 
|  |  | 
|  |  | 
|  | def main(argv): | 
|  | if (len(argv) < 4): | 
|  | return usage(argv, "Wrong number of arguments!") | 
|  | pgconfs = [] | 
|  | injars = [] | 
|  | libraryjars = [] | 
|  | i = 2 | 
|  | while i < len(argv): | 
|  | directive = argv[i] | 
|  | if directive not in ['--pgconf', '--injar', '--libraryjar']: | 
|  | return usage( | 
|  | argv, | 
|  | 'Unexpected argument, expected one of --pgconf, --injar, and ' | 
|  | + '--libraryjar.') | 
|  | if i + 1 >= len(argv): | 
|  | return usage(argv, 'Expected argument after ' + directive + '.') | 
|  | file = argv[i + 1] | 
|  | if directive == '--pgconf': | 
|  | pgconfs.append(file) | 
|  | elif directive == '--injar': | 
|  | injars.append(file) | 
|  | elif directive == '--libraryjar': | 
|  | libraryjars.append(file) | 
|  | i = i + 2 | 
|  | SanitizeLibrariesInPgconf(argv[0], argv[1], pgconfs, injars, libraryjars) | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | sys.exit(main(sys.argv[1:])) |