From aba6bb0bbd1537a6df9614ee579773e4a8af70ff Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Sun, 24 Jan 2010 20:14:53 +0000 Subject: [PATCH] Implemented verification for if-eq and if-ne git-svn-id: https://smali.googlecode.com/svn/trunk@583 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../dexlib/Code/Analysis/MethodAnalyzer.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java index a8054772..7161b363 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java @@ -484,6 +484,9 @@ public class MethodAnalyzer { case CMPG_DOUBLE: case CMP_LONG: return handleWideCmp(analyzedInstruction); + case IF_EQ: + case IF_NE: + return handleIfEqNe(analyzedInstruction); } assert false; return false; @@ -1248,6 +1251,37 @@ public class MethodAnalyzer { return true; } + private boolean handleIfEqNe(AnalyzedInstruction analyzedInstruction) { + TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; + + RegisterType registerType1 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); + assert registerType1 != null; + if (registerType1.category == RegisterType.Category.Unknown) { + return false; + } + + RegisterType registerType2 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); + assert registerType2 != null; + if (registerType2.category == RegisterType.Category.Unknown) { + return false; + } + + if (!( + (ReferenceCategories.contains(registerType1.category) && + ReferenceCategories.contains(registerType2.category)) + || + (Primitive32BitCategories.contains(registerType1.category) && + Primitive32BitCategories.contains(registerType2.category)) + )) { + + throw new ValidationException(String.format("%s cannot be used on registers of dissimilar types %s and " + + "%s. They must both be a reference type or a primitive 32 bit type.", + analyzedInstruction.instruction.opcode.name, registerType1.toString(), registerType2.toString())); + } + + return true; + } + private static void checkRegister(RegisterType registerType, EnumSet validCategories) { if (!validCategories.contains(registerType.category)) { //TODO: add expected categories to error message