From 052f4890ab954dc8510230b2992904a1a66c5dcc Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Wed, 27 Jan 2010 04:37:16 +0000 Subject: [PATCH] Implemented verification for sget/sget-boolean/sget-byte/sget-char/sget-short git-svn-id: https://smali.googlecode.com/svn/trunk@599 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 31dde52c..b3ad44ae 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 @@ -556,6 +556,16 @@ public class MethodAnalyzer { return handleIputWide(analyzedInstruction); case IPUT_OBJECT: return handleIputObject(analyzedInstruction); + case SGET: + return handle32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer); + case SGET_BOOLEAN: + return handle32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean); + case SGET_BYTE: + return handle32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte); + case SGET_CHAR: + return handle32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char); + case SGET_SHORT: + return handle32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short); } assert false; @@ -1977,6 +1987,30 @@ public class MethodAnalyzer { return true; } + private boolean handle32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction, + RegisterType.Category instructionCategory) { + SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; + + //TODO: check access + //TODO: allow an uninitialized "this" reference, if the current method is an method + Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); + assert referencedItem instanceof FieldIdItem; + FieldIdItem field = (FieldIdItem)referencedItem; + + RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); + + if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { + throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + + "for the instruction.", analyzedInstruction.instruction.opcode.name, + field.getFieldString())); + } + + setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, + RegisterType.getRegisterType(instructionCategory, null)); + + return true; + } + private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory, RegisterType.Category instructionCategory) { if (arrayFieldCategory == instructionCategory) {