# HG changeset patch # User Thinker K.F. Li # Date 1311597452 -28800 # Node ID c0c127c7b37e8c123f566baf16939c9f56d9c256 # Parent 00cd331f8aa8eae9e5787bfa1dab0fca51e4e718 Check and fix issues of map sizes diff -r 00cd331f8aa8 -r c0c127c7b37e paraspace/dexfile.py --- a/paraspace/dexfile.py Mon Jul 25 17:46:20 2011 +0800 +++ b/paraspace/dexfile.py Mon Jul 25 20:37:32 2011 +0800 @@ -979,7 +979,8 @@ child_names = \ 'classIdx accessFlags superclassIdx interfacesOff interfacesOffRef ' \ 'sourceFileIdx annotationsOff annotationsOffRef ' \ - 'classDataOff staticValuesOff staticValuesOffRef'.split() + 'classDataOff classDataOffRef staticValuesOff ' \ + 'staticValuesOffRef'.split() pass @@ -1702,10 +1703,28 @@ pass raise ValueError, 'can not find class definition for \'%s\'' % (name) + ## \brief Update size of map items. + # + # Corresponding data lists of maps may be changed, it should be updated + # before restore dependencies and keep it consistent. + # + def _update_map_sizes(self): + for mapitem in self.maps.items.items: + attr = DEXFile.block_defs[mapitem.type] + datalist = getattr(self, attr) + if isinstance(datalist, array): + mapitem.size = len(datalist.items) + pass + pass + pass + + ## \brief Return an unlinked version. def get_unlinked(self): from paraspace.dex_deptracker import restore_dependencies + + self._update_map_sizes() + unlinked = DEXFile() - for attr, value in self.__dict__.items(): setattr(unlinked, attr, value) pass diff -r 00cd331f8aa8 -r c0c127c7b37e paraspace/injection.py --- a/paraspace/injection.py Mon Jul 25 17:46:20 2011 +0800 +++ b/paraspace/injection.py Mon Jul 25 20:37:32 2011 +0800 @@ -37,10 +37,17 @@ def dex_type_2_array_attr_map(): global dex_type_2_array_attr_map from paraspace.dexfile import DEXFile, array + from paraspace.dex_deptracker import _marker + + def skip_marker_type(clazz): + while isinstance(clazz, _marker): + clazz = clazz.back_type + pass + return clazz attr_values = [(attr, getattr(DEXFile, attr)) for attr in dir(DEXFile)] - type_2_attr = dict([(value.child_type, attr) + type_2_attr = dict([(skip_marker_type(value.child_type), attr) for attr, value in attr_values if isinstance(value, array)]) diff -r 00cd331f8aa8 -r c0c127c7b37e paraspace/tests/injection_test.py --- a/paraspace/tests/injection_test.py Mon Jul 25 17:46:20 2011 +0800 +++ b/paraspace/tests/injection_test.py Mon Jul 25 20:37:32 2011 +0800 @@ -19,6 +19,14 @@ pass +def _find_map(dex, map_type): + for map in dex.maps.items.items: + if map.type == map_type: + return map + pass + pass + + def inject_fakefile_to_helloworld_test(): from paraspace.dex_deptracker import prepare_dep_decls from paraspace.injection import dexfile_insert_class @@ -32,6 +40,10 @@ helloworld_fn = os.path.join(srcroot, 'data', 'helloworld.dex') helloworld_dex = dexfile.DEXFile.open(helloworld_fn) + + classdef_map = _find_map(helloworld_dex, 0x0006) + saved_classdef_map_sz = classdef_map.size + helloworld_linked = \ dexfile.DEXFile_linked.build_dependencies(helloworld_dex, all_dep_decls) @@ -45,11 +57,18 @@ fakefile_def = fakefile_linked. \ find_class_name('Lcom/codemud/fakefile/fakefile;') - clone = dexfile_insert_class(helloworld_dex, fakefile_def) + clone = dexfile_insert_class(helloworld_linked, fakefile_def) assert clone assert clone != fakefile_def helloworld_unlinked = helloworld_linked.get_unlinked() assert helloworld_unlinked + + # map size for classdef must be increased by 1 + classdef_map = _find_map(helloworld_unlinked, 0x0006) + assert classdef_map.size == saved_classdef_map_sz + 1 + + classdata_map = _find_map(helloworld_unlinked, 0x2000) + assert classdata_map.size == classdef_map.size pass