Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env python3
      2 
      3 from __future__ import print_function
      4 
      5 import os
      6 import subprocess
      7 import sys
      8 import unittest
      9 import zipfile
     10 
     11 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
     12 
     13 from compat import TemporaryDirectory
     14 from vndk_definition_tool import DexFileReader
     15 
     16 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
     17 INPUT_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_dex_file')
     18 
     19 
     20 class ModifiedUTF8Test(unittest.TestCase):
     21     def test_encode(self):
     22         self.assertEqual(b'\xc0\x80', u'\u0000'.encode('mutf-8'))
     23         self.assertEqual(b'\x09', u'\u0009'.encode('mutf-8'))
     24         self.assertEqual(b'\x7f', u'\u007f'.encode('mutf-8'))
     25         self.assertEqual(b'\xc2\x80', u'\u0080'.encode('mutf-8'))
     26         self.assertEqual(b'\xdf\xbf', u'\u07ff'.encode('mutf-8'))
     27         self.assertEqual(b'\xe0\xa0\x80', u'\u0800'.encode('mutf-8'))
     28         self.assertEqual(b'\xe7\xbf\xbf', u'\u7fff'.encode('mutf-8'))
     29         self.assertEqual(b'\xed\xa0\x81\xed\xb0\x80',
     30                          u'\U00010400'.encode('mutf-8'))
     31 
     32 
     33     def test_decode(self):
     34         self.assertEqual(u'\u0000', b'\xc0\x80'.decode('mutf-8'))
     35         self.assertEqual(u'\u0009', b'\x09'.decode('mutf-8'))
     36         self.assertEqual(u'\u007f', b'\x7f'.decode('mutf-8'))
     37         self.assertEqual(u'\u0080', b'\xc2\x80'.decode('mutf-8'))
     38         self.assertEqual(u'\u07ff', b'\xdf\xbf'.decode('mutf-8'))
     39         self.assertEqual(u'\u0800', b'\xe0\xa0\x80'.decode('mutf-8'))
     40         self.assertEqual(u'\u7fff', b'\xe7\xbf\xbf'.decode('mutf-8'))
     41         self.assertEqual(u'\U00010400',
     42                          b'\xed\xa0\x81\xed\xb0\x80'.decode('mutf-8'))
     43 
     44 
     45 class DexFileTest(unittest.TestCase):
     46     def _assemble_smali(self, dest, source):
     47         """Assemble a smali source file.  Skip the test if the smali command is
     48         unavailable."""
     49         try:
     50             subprocess.check_call(['smali', 'a', source, '-o', dest])
     51         except IOError:
     52             self.skipTest('smali not available')
     53 
     54 
     55     def _create_zip_file(self, dest, paths):
     56         """Create a zip file from several input files."""
     57         with zipfile.ZipFile(dest, 'w') as zip_file:
     58             for path in paths:
     59                 zip_file.write(path, os.path.basename(path))
     60 
     61 
     62     def test_generate_classes_dex_names(self):
     63         seq = DexFileReader.generate_classes_dex_names()
     64         self.assertEqual('classes.dex', next(seq))
     65         self.assertEqual('classes2.dex', next(seq))
     66         self.assertEqual('classes3.dex', next(seq))
     67 
     68 
     69     def test_enumerate_dex_strings_buf(self):
     70         with TemporaryDirectory() as tmp_dir:
     71             smali_file = os.path.join(INPUT_DIR, 'Hello.smali')
     72             classes_dex = os.path.join(tmp_dir, 'classes.dex')
     73             self._assemble_smali(classes_dex, smali_file)
     74 
     75             with open(classes_dex, 'rb') as classes_dex:
     76                 buf = classes_dex.read()
     77 
     78             strs = set(DexFileReader.enumerate_dex_strings_buf(buf))
     79 
     80             self.assertIn('hello', strs)
     81             self.assertIn('world', strs)
     82 
     83 
     84     def test_enumerate_dex_strings_apk(self):
     85         with TemporaryDirectory() as tmp_dir:
     86             smali_file = os.path.join(INPUT_DIR, 'Hello.smali')
     87             classes_dex = os.path.join(tmp_dir, 'classes.dex')
     88             self._assemble_smali(classes_dex, smali_file)
     89 
     90             smali_file = os.path.join(INPUT_DIR, 'Example.smali')
     91             classes2_dex = os.path.join(tmp_dir, 'classes2.dex')
     92             self._assemble_smali(classes2_dex, smali_file)
     93 
     94             zip_file = os.path.join(tmp_dir, 'example.apk')
     95             self._create_zip_file(zip_file, [classes_dex, classes2_dex])
     96 
     97             strs = set(DexFileReader.enumerate_dex_strings_apk(zip_file))
     98 
     99             self.assertIn('hello', strs)
    100             self.assertIn('world', strs)
    101             self.assertIn('foo', strs)
    102             self.assertIn('bar', strs)
    103 
    104 
    105 if __name__ == '__main__':
    106     unittest.main()
    107