Mercurial > paraspace
changeset 98:c0c127c7b37e
Check and fix issues of map sizes
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 25 Jul 2011 20:37:32 +0800 |
parents | 00cd331f8aa8 |
children | 3898711adb2c |
files | paraspace/dexfile.py paraspace/injection.py paraspace/tests/injection_test.py |
diffstat | 3 files changed, 49 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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)])
--- 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