changeset 100:355986e5cfbd

Make surce methods of injected class are also being and bug fixed. - dex_type_2_array_attr_map() misses marked array attributes. - It is fixed by skiping marked array and use back type instead.
author Thinker K.F. Li <thinker@codemud.net>
date Tue, 26 Jul 2011 10:06:44 +0800
parents 3898711adb2c
children b2db11aed6b8
files paraspace/injection.py paraspace/tests/injection_test.py
diffstat 2 files changed, 34 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/paraspace/injection.py	Mon Jul 25 21:53:33 2011 +0800
+++ b/paraspace/injection.py	Tue Jul 26 10:06:44 2011 +0800
@@ -1,6 +1,14 @@
 
 def _relocatable_children(obj):
-    from paraspace.dexfile import relocatable
+    from paraspace.dexfile import relocatable, array
+    
+    if isinstance(obj, array):
+        if not obj.items:
+            return []
+        rel_children = [(repr(idx), elt)
+                        for idx, elt in enumerate(obj.items)
+                        if isinstance(elt, relocatable)]
+        return rel_children
     
     attr_value_pairs = [(attr, getattr(obj, attr)) for attr in dir(obj)]
     rel_children = [(attr, value) for attr, value in attr_value_pairs
@@ -45,11 +53,12 @@
             pass
         return clazz
     
-    attr_values = [(attr, getattr(DEXFile, attr))
+    attr_values = [(attr, skip_marker_type(getattr(DEXFile, attr)))
                    for attr in dir(DEXFile)]
-    type_2_attr = dict([(skip_marker_type(value.child_type), attr)
-                        for attr, value in attr_values
-                        if isinstance(value, array)])
+    array_attrs = [(skip_marker_type(value.child_type), attr)
+                   for attr, value in attr_values
+                   if isinstance(value, array)]
+    type_2_attr = dict(array_attrs)
     
     dex_type_2_array_attr_map = lambda: type_2_attr
     
--- a/paraspace/tests/injection_test.py	Mon Jul 25 21:53:33 2011 +0800
+++ b/paraspace/tests/injection_test.py	Tue Jul 26 10:06:44 2011 +0800
@@ -43,6 +43,10 @@
 
     classdef_map = _find_map(helloworld_dex, 0x0006)
     saved_classdef_map_sz = classdef_map.size
+    saved_methodids_sz = len(helloworld_dex.methodIds.items)
+    
+    codeitems_map = _find_map(helloworld_dex, 0x2001)
+    saved_codeitems_sz = codeitems_map.size
 
     helloworld_linked = \
         dexfile.DEXFile_linked.build_dependencies(helloworld_dex,
@@ -57,6 +61,13 @@
     fakefile_def = fakefile_linked. \
         find_class_name('Lcom/codemud/fakefile/fakefile;')
 
+    fakefile_data = fakefile_def.classDataOffRef.value
+    assert len(fakefile_data.directMethods.items) == 1
+    assert len(fakefile_data.virtualMethods.items) == 0
+    fakefile_dataheader = fakefile_data.header
+    assert fakefile_dataheader.directMethodsSize == 1
+    assert fakefile_dataheader.virtualMethodsSize == 0
+
     clone = dexfile_insert_class(helloworld_linked, fakefile_def)
     assert clone
     assert clone != fakefile_def
@@ -76,5 +87,14 @@
     strs = sorted([strdata.data.data for strdata in strdatas])
     assert len(strs) == len(set(strs)) # uniquely
     assert 'Lcom/codemud/fakefile/fakefile;' in strs
+
+    # Check Method List
+    methodids_map = _find_map(helloworld_unlinked, 0x0005) # method ids
+    assert methodids_map.size == len(helloworld_unlinked.methodIds.items)
+    assert methodids_map.size == saved_methodids_sz + 1
+
+    # Check Code item List
+    codeitems_map = _find_map(helloworld_unlinked, 0x2001)
+    assert codeitems_map.size == saved_codeitems_sz + 1
     pass