■ ■ ■ ■ ■ ■
jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java
| skipped 89 lines |
90 | 90 | | for (ArgType superType : superData.getSuperTypes()) { |
91 | 91 | | ClassNode classNode = mth.root().resolveClass(superType); |
92 | 92 | | if (classNode != null) { |
93 | | - | MethodNode ovrdMth = searchOverriddenMethod(classNode, signature); |
| 93 | + | MethodNode ovrdMth = searchOverriddenMethod(classNode, mth, signature); |
94 | 94 | | if (ovrdMth != null) { |
95 | 95 | | if (isMethodVisibleInCls(ovrdMth, cls)) { |
96 | 96 | | overrideList.add(ovrdMth); |
| skipped 10 lines |
107 | 107 | | Map<String, ClspMethod> methodsMap = clsDetails.getMethodsMap(); |
108 | 108 | | for (Map.Entry<String, ClspMethod> entry : methodsMap.entrySet()) { |
109 | 109 | | String mthShortId = entry.getKey(); |
| 110 | + | // do not check full signature, classpath methods can be trusted |
| 111 | + | // i.e. doesn't contain methods with same signature in one class |
110 | 112 | | if (mthShortId.startsWith(signature)) { |
111 | 113 | | overrideList.add(entry.getValue()); |
112 | 114 | | break; |
| skipped 17 lines |
130 | 132 | | } |
131 | 133 | | |
132 | 134 | | @Nullable |
133 | | - | private MethodNode searchOverriddenMethod(ClassNode cls, String signature) { |
| 135 | + | private MethodNode searchOverriddenMethod(ClassNode cls, MethodNode mth, String signature) { |
| 136 | + | // search by exact full signature (with return value) to fight obfuscation (see test |
| 137 | + | // 'TestOverrideWithSameName') |
| 138 | + | String shortId = mth.getMethodInfo().getShortId(); |
134 | 139 | | for (MethodNode supMth : cls.getMethods()) { |
135 | | - | if (!supMth.getAccessFlags().isStatic() && supMth.getMethodInfo().getShortId().startsWith(signature)) { |
| 140 | + | if (supMth.getMethodInfo().getShortId().equals(shortId) && !supMth.getAccessFlags().isStatic()) { |
136 | 141 | | return supMth; |
| 142 | + | } |
| 143 | + | } |
| 144 | + | // search by signature without return value and check if return value is wider type |
| 145 | + | for (MethodNode supMth : cls.getMethods()) { |
| 146 | + | if (supMth.getMethodInfo().getShortId().startsWith(signature) && !supMth.getAccessFlags().isStatic()) { |
| 147 | + | TypeCompare typeCompare = cls.root().getTypeCompare(); |
| 148 | + | ArgType supRetType = supMth.getMethodInfo().getReturnType(); |
| 149 | + | ArgType mthRetType = mth.getMethodInfo().getReturnType(); |
| 150 | + | TypeCompareEnum res = typeCompare.compareTypes(supRetType, mthRetType); |
| 151 | + | if (res.isWider()) { |
| 152 | + | return supMth; |
| 153 | + | } |
| 154 | + | if (res == TypeCompareEnum.UNKNOWN || res == TypeCompareEnum.CONFLICT) { |
| 155 | + | mth.addDebugComment("Possible override for method " + supMth.getMethodInfo().getFullId()); |
| 156 | + | } |
137 | 157 | | } |
138 | 158 | | } |
139 | 159 | | return null; |
| skipped 305 lines |