mirror of
https://github.com/revanced/smali.git
synced 2025-05-02 23:54:38 +02:00
Don't propagate a non-narrowing conversion through a move
This commit is contained in:
parent
9f794030da
commit
d13be24e27
@ -1166,6 +1166,18 @@ public class MethodAnalyzer {
|
||||
setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, castRegisterType);
|
||||
}
|
||||
|
||||
private static boolean isNarrowingConversion(RegisterType originalType, RegisterType newType) {
|
||||
if (originalType.type == null || newType.type == null) {
|
||||
return false;
|
||||
}
|
||||
if (originalType.type.isInterface()) {
|
||||
return newType.type.implementsInterface(originalType.type.getType());
|
||||
} else {
|
||||
TypeProto commonSuperclass = newType.type.getCommonSuperclass(originalType.type);
|
||||
return commonSuperclass.getType().equals(originalType.type.getType());
|
||||
}
|
||||
}
|
||||
|
||||
static boolean canNarrowAfterInstanceOf(AnalyzedInstruction analyzedInstanceOfInstruction,
|
||||
AnalyzedInstruction analyzedIfInstruction, ClassPath classPath) {
|
||||
Instruction ifInstruction = analyzedIfInstruction.instruction;
|
||||
@ -1179,18 +1191,7 @@ public class MethodAnalyzer {
|
||||
|
||||
RegisterType originalType = analyzedIfInstruction.getPreInstructionRegisterType(objectRegister);
|
||||
|
||||
if (originalType.type != null) {
|
||||
// Only override if we're going from an interface to a class, or are going to a narrower class
|
||||
if (originalType.type.isInterface()) {
|
||||
return true;
|
||||
} else {
|
||||
TypeProto commonSuperclass = registerType.type.getCommonSuperclass(originalType.type);
|
||||
// only if it's a narrowing conversion
|
||||
if (commonSuperclass.getType().equals(originalType.type.getType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isNarrowingConversion(originalType, registerType);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -1210,6 +1211,9 @@ public class MethodAnalyzer {
|
||||
if (canNarrowAfterInstanceOf(prevAnalyzedInstruction, analyzedInstruction, classPath)) {
|
||||
List<Integer> narrowingRegisters = Lists.newArrayList();
|
||||
|
||||
RegisterType newType = RegisterType.getRegisterType(classPath,
|
||||
(TypeReference)((Instruction22c)prevAnalyzedInstruction.instruction).getReference());
|
||||
|
||||
if (instructionIndex > 1) {
|
||||
// If we have something like:
|
||||
// move-object/from16 v0, p1
|
||||
@ -1221,17 +1225,24 @@ public class MethodAnalyzer {
|
||||
Opcode opcode = prevPrevAnalyzedInstruction.instruction.getOpcode();
|
||||
if (opcode == Opcode.MOVE_OBJECT || opcode == Opcode.MOVE_OBJECT_16 ||
|
||||
opcode == Opcode.MOVE_OBJECT_FROM16) {
|
||||
TwoRegisterInstruction moveInstruction =
|
||||
((TwoRegisterInstruction)prevPrevAnalyzedInstruction.instruction);
|
||||
RegisterType originalType =
|
||||
prevPrevAnalyzedInstruction.getPostInstructionRegisterType(
|
||||
moveInstruction.getRegisterB());
|
||||
if (originalType.type != null) {
|
||||
if (isNarrowingConversion(originalType, newType)) {
|
||||
narrowingRegisters.add(
|
||||
((TwoRegisterInstruction)prevPrevAnalyzedInstruction.instruction).getRegisterB());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate the original type to the failing branch, and the new type to the successful branch
|
||||
int narrowingRegister = ((Instruction22c)prevAnalyzedInstruction.instruction).getRegisterB();
|
||||
narrowingRegisters.add(narrowingRegister);
|
||||
RegisterType originalType = analyzedInstruction.getPreInstructionRegisterType(narrowingRegister);
|
||||
RegisterType newType = RegisterType.getRegisterType(classPath,
|
||||
(TypeReference)((Instruction22c)prevAnalyzedInstruction.instruction).getReference());
|
||||
|
||||
AnalyzedInstruction fallthroughInstruction = analyzedInstructions.valueAt(
|
||||
analyzedInstruction.getInstructionIndex() + 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user