changeset 116:c5f59bdbc916

Fix issue of proto matching. - DEXFile_linked._proto_is_compatible() compares return type of prototypes in _DEX_TypeId objects. - It should match them with type name.
author Thinker K.F. Li <thinker@codemud.net>
date Thu, 04 Aug 2011 18:30:11 +0800
parents d112c27f657a
children 2833c1337dc0
files paraspace/dexfile.py paraspace/tests/injection_test.py
diffstat 2 files changed, 49 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/paraspace/dexfile.py	Thu Aug 04 15:55:01 2011 +0800
+++ b/paraspace/dexfile.py	Thu Aug 04 18:30:11 2011 +0800
@@ -1839,7 +1839,9 @@
     ## \brief Test if prototype of two methods are compatible.
     @staticmethod
     def _proto_is_compatible(proto1, proto2):
-        if proto1.returnTypeIdx != proto2.returnTypeIdx:
+        rtypename1 = DEXFile_linked.get_typeid_name(proto1.returnTypeIdx)
+        rtypename2 = DEXFile_linked.get_typeid_name(proto2.returnTypeIdx)
+        if rtypename1 != rtypename2:
             return False
         typelist1 = proto1.parametersOffRef.value
         typelist2 = proto2.parametersOffRef.value
@@ -1944,6 +1946,29 @@
         ptype_names = [DEXFile_linked.get_typeid_name(ptype)
                        for ptype in param_types]
         return '(%s) --> %s' % (', '.join(ptype_names), rtype_name)
+
+    @staticmethod
+    def make_protoid(rtype, args):
+        arglist = _DEX_TypeList()
+        arglist.num = len(args)
+        arglist.typeItems = array(None, _DEX_TypeList_typeid)
+        
+        tltypeid_args = [_DEX_TypeList_typeid()
+                         for arg in args]
+        for tltypeid, arg in map(None, tltypeid_args, args):
+            tltypeid.typeIdx = arg
+            pass
+        
+        arglist.typeItems.items = tltypeid_args
+
+        param_cond = cond(None, _DEX_TypeList)
+        param_cond.value = arglist
+        param_cond.is_true = True
+        
+        protoid = _DEX_ProtoId()
+        protoid.returnTypeIdx = rtype
+        protoid.parametersOffRef = param_cond
+        return protoid
     pass
 
 
--- a/paraspace/tests/injection_test.py	Thu Aug 04 15:55:01 2011 +0800
+++ b/paraspace/tests/injection_test.py	Thu Aug 04 18:30:11 2011 +0800
@@ -299,6 +299,7 @@
     from paraspace.dex_deptracker import prepare_dep_decls
     from paraspace.injection import inject_classdefs
     from paraspace import dalvik_opcodes
+    from paraspace.dexfile import DEXFile_linked
     
     _install_dexfile_4_deptracker()
     
@@ -333,4 +334,26 @@
                                 [fakefile_def])
     assert clonings
     assert len(clonings) == 1
+
+    fakefile_cloning = clonings[0]
+    method = helloworld_linked.find_method_name('<init>', fakefile_cloning)
+    assert isinstance(method, dexfile._DEX_Method)
+
+    V_typeid = helloworld_linked.find_typeid_name('V')
+    file_typeid = helloworld_linked.find_typeid_name('Ljava/io/File;')
+    file_typeidx = helloworld_linked.get_idx_typeid(file_typeid)
+    str_typeid = helloworld_linked.find_typeid_name('Ljava/lang/String;')
+    protoid = DEXFile_linked.make_protoid(V_typeid,
+                                          (file_typeid, str_typeid))
+    initid = helloworld_linked.find_methodid_name_proto('<init>',
+                                                        protoid,
+                                                        file_typeid)
+    initidx = helloworld_linked.get_idx_methodid(initid)
+
+    insns_block = DEXFile_linked.get_code_block_method(method)
+    opvectors = dalvik_opcodes.decode_insn_blk(insns_block)
+    assert len(opvectors) == 2
+    opvector = opvectors[0]
+    args = opvector[1]
+    assert args[2] == initidx
     pass