Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2013 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the 'License');
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an 'AS IS' BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 """Check that a jar file contains only allowed packages.
     19 
     20 Given a jar file (typically, the result of running jarjar to rename packages)
     21 and a whitelist file of allowed package names, one per line, check that all the
     22 classes in the jar are in one of those packages.
     23 """
     24 
     25 import contextlib
     26 import sys
     27 import zipfile
     28 
     29 
     30 def JarCheck(jar_path, whitelist_path):
     31   """Checks that the files in the jar are in whitelisted packages.
     32 
     33   Args:
     34     jar_path: The path to the .jar file to be checked.
     35     whitelist_path: The path to the whitelist file.
     36   Returns:
     37     A list of files that are not in whitelisted packages.
     38   """
     39   with open(whitelist_path) as whitelist_file:
     40     allowed_packages = tuple(x.replace('.', '/').replace('\n', '/')
     41                              for x in whitelist_file)
     42 
     43   with contextlib.closing(zipfile.ZipFile(jar_path)) as jar:
     44     jar_contents = jar.namelist()
     45 
     46   invalid_files = []
     47   for filename in jar_contents:
     48     # Zipfile entries with a trailing / are directories, we can ignore these.
     49     # Also ignore jar meta-info.
     50     if filename.endswith('/') or filename.startswith('META-INF/'):
     51       continue
     52     if not filename.startswith(allowed_packages):
     53       invalid_files.append(filename)
     54 
     55   return invalid_files
     56 
     57 
     58 def main(argv):
     59   if len(argv) != 3:
     60     print >>sys.stderr, 'Usage: %s jar_file whitelist_file' % argv[0]
     61     return 2
     62   invalid_files = JarCheck(argv[1], argv[2])
     63   invalid_file_count = len(invalid_files)
     64   if invalid_file_count == 0:
     65     return 0
     66   print >>sys.stderr, ('jar_check found %s files not in a whitelisted package:'
     67                        % invalid_file_count)
     68   for f in invalid_files:
     69     print >>sys.stderr, f
     70   return 1
     71 
     72 
     73 if __name__ == '__main__':
     74   sys.exit(main(sys.argv))
     75