From 60631f684fe900940670409c46b7752c5713ae51 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Fri, 9 Nov 2012 23:09:23 -0800 Subject: [PATCH] Detect static final fields that are set in the static initializer --- .../jf/baksmali/Adaptors/ClassDefinition.java | 27 +++++++++++-------- .../org/jf/dexlib2/util/ReferenceUtil.java | 9 +++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java index 720c856d..c783f7d6 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java @@ -30,30 +30,34 @@ package org.jf.baksmali.Adaptors; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.iface.*; +import org.jf.dexlib2.iface.instruction.Instruction; +import org.jf.dexlib2.iface.instruction.formats.Instruction21c; +import org.jf.dexlib2.iface.reference.FieldReference; +import org.jf.dexlib2.util.ReferenceUtil; import org.jf.util.StringUtils; import org.jf.util.IndentingWriter; import javax.annotation.Nonnull; import java.io.IOException; +import java.util.HashSet; import java.util.List; public class ClassDefinition { @Nonnull public final ClassDef classDef; - //@Nonnull private final HashSet fieldsSetInStaticConstructor; + @Nonnull private final HashSet fieldsSetInStaticConstructor; protected boolean validationErrors; public ClassDefinition(ClassDef classDef) { this.classDef = classDef; - //fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor(); + fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor(); } public boolean hadValidationErrors() { return validationErrors; } - //TODO: uncomment - /*@Nonnull + @Nonnull private HashSet findFieldsSetInStaticConstructor() { HashSet fieldsSetInStaticConstructor = new HashSet(); @@ -71,9 +75,9 @@ public class ClassDefinition { case SPUT_SHORT: case SPUT_WIDE: { Instruction21c ins = (Instruction21c)instruction; - String field = ins.getReference(); - if (field.startsWith(classDef.getName())) { - fieldsSetInStaticConstructor.add(field); + FieldReference fieldRef = (FieldReference)ins.getReference(); + if (fieldRef.getContainingClass().equals((classDef.getType()))) { + fieldsSetInStaticConstructor.add(ReferenceUtil.getShortFieldDescriptor(fieldRef)); } break; } @@ -83,7 +87,7 @@ public class ClassDefinition { } } return fieldsSetInStaticConstructor; - }*/ + } public void writeTo(IndentingWriter writer) throws IOException { writeClass(writer); @@ -162,9 +166,11 @@ public class ClassDefinition { } writer.write('\n'); // TODO: detect duplicate fields. - // TODO: check if field is set in static constructor - FieldDefinition.writeTo(writer, field, false); + boolean setInStaticConstructor = + fieldsSetInStaticConstructor.contains(ReferenceUtil.getShortFieldDescriptor(field)); + + FieldDefinition.writeTo(writer, field, setInStaticConstructor); } } } @@ -180,7 +186,6 @@ public class ClassDefinition { } writer.write('\n'); // TODO: detect duplicate fields. - // TODO: check if field is set in static constructor FieldDefinition.writeTo(writer, field, false); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java index 7925dc17..c9d401c8 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java @@ -77,6 +77,15 @@ public abstract class ReferenceUtil { return sb.toString(); } + public static String getShortFieldDescriptor(FieldReference fieldReference) { + // TODO: try using a thread local StringBuilder + StringBuilder sb = new StringBuilder(); + sb.append(fieldReference.getName()); + sb.append(':'); + sb.append(fieldReference.getType()); + return sb.toString(); + } + public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference) throws IOException { writer.write(fieldReference.getContainingClass()); writer.write("->");