From ed140ca3e4fa66a03970affb3415a9fe2a924312 Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Sun, 24 Jan 2010 19:17:41 +0000 Subject: [PATCH] Implemented verification for throw git-svn-id: https://smali.googlecode.com/svn/trunk@578 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../dexlib/Code/Analysis/MethodAnalyzer.java | 31 +++++++++++++++++++ 1 file changed, 31 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 eaaf9c61..757ba378 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 @@ -466,6 +466,8 @@ public class MethodAnalyzer { return handleFilledNewArrayRange(analyzedInstruction); case FILL_ARRAY_DATA: return handleFillArrayData(analyzedInstruction); + case THROW: + return handleThrow(analyzedInstruction); } assert false; return false; @@ -1131,6 +1133,35 @@ public class MethodAnalyzer { return true; } + private boolean handleThrow(AnalyzedInstruction analyzedInstruction) { + int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); + + RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); + assert registerType != null; + + if (registerType.category == RegisterType.Category.Unknown) { + return false; + } + + if (registerType.category == RegisterType.Category.Null) { + return true; + } + + if (registerType.category != RegisterType.Category.Reference) { + throw new ValidationException(String.format("Cannot use throw with non-reference type %s in register v%d", + registerType.toString(), register)); + } + + assert registerType.type != null; + + if (!registerType.type.extendsClass(ClassPath.getClassDef("Ljava/lang/Throwable;"))) { + throw new ValidationException(String.format("Cannot use throw with non-throwable type %s in register v%d", + registerType.type.getClassType(), register)); + } + + return true; + } + private static void checkRegister(RegisterType registerType, EnumSet validCategories) { if (!validCategories.contains(registerType.category)) { //TODO: add expected categories to error message