Detect static final fields that are set in the static initializer

This commit is contained in:
Ben Gruver 2012-11-09 23:09:23 -08:00
parent 987cdc3e0e
commit 60631f684f
2 changed files with 25 additions and 11 deletions

View File

@ -30,30 +30,34 @@ package org.jf.baksmali.Adaptors;
import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.iface.*; 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.StringUtils;
import org.jf.util.IndentingWriter; import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
import java.util.List; import java.util.List;
public class ClassDefinition { public class ClassDefinition {
@Nonnull public final ClassDef classDef; @Nonnull public final ClassDef classDef;
//@Nonnull private final HashSet<String> fieldsSetInStaticConstructor; @Nonnull private final HashSet<String> fieldsSetInStaticConstructor;
protected boolean validationErrors; protected boolean validationErrors;
public ClassDefinition(ClassDef classDef) { public ClassDefinition(ClassDef classDef) {
this.classDef = classDef; this.classDef = classDef;
//fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor(); fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();
} }
public boolean hadValidationErrors() { public boolean hadValidationErrors() {
return validationErrors; return validationErrors;
} }
//TODO: uncomment @Nonnull
/*@Nonnull
private HashSet<String> findFieldsSetInStaticConstructor() { private HashSet<String> findFieldsSetInStaticConstructor() {
HashSet<String> fieldsSetInStaticConstructor = new HashSet<String>(); HashSet<String> fieldsSetInStaticConstructor = new HashSet<String>();
@ -71,9 +75,9 @@ public class ClassDefinition {
case SPUT_SHORT: case SPUT_SHORT:
case SPUT_WIDE: { case SPUT_WIDE: {
Instruction21c ins = (Instruction21c)instruction; Instruction21c ins = (Instruction21c)instruction;
String field = ins.getReference(); FieldReference fieldRef = (FieldReference)ins.getReference();
if (field.startsWith(classDef.getName())) { if (fieldRef.getContainingClass().equals((classDef.getType()))) {
fieldsSetInStaticConstructor.add(field); fieldsSetInStaticConstructor.add(ReferenceUtil.getShortFieldDescriptor(fieldRef));
} }
break; break;
} }
@ -83,7 +87,7 @@ public class ClassDefinition {
} }
} }
return fieldsSetInStaticConstructor; return fieldsSetInStaticConstructor;
}*/ }
public void writeTo(IndentingWriter writer) throws IOException { public void writeTo(IndentingWriter writer) throws IOException {
writeClass(writer); writeClass(writer);
@ -162,9 +166,11 @@ public class ClassDefinition {
} }
writer.write('\n'); writer.write('\n');
// TODO: detect duplicate fields. // 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'); writer.write('\n');
// TODO: detect duplicate fields. // TODO: detect duplicate fields.
// TODO: check if field is set in static constructor
FieldDefinition.writeTo(writer, field, false); FieldDefinition.writeTo(writer, field, false);
} }

View File

@ -77,6 +77,15 @@ public abstract class ReferenceUtil {
return sb.toString(); 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 { public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference) throws IOException {
writer.write(fieldReference.getContainingClass()); writer.write(fieldReference.getContainingClass());
writer.write("->"); writer.write("->");