1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import java.util.*; 25 import org.apache.bcel.classfile.*; 26 27 public class FindUninitializedGet extends BytecodeScanningDetector implements StatelessDetector { 28 Set<FieldAnnotation> initializedFields = new HashSet<FieldAnnotation>(); 29 Set<FieldAnnotation> declaredFields = new HashSet<FieldAnnotation>(); 30 Collection<BugInstance> pendingBugs = new LinkedList<BugInstance>(); 31 boolean inConstructor; 32 boolean thisOnTOS = false; 33 private BugReporter bugReporter; 34 35 private static final int UNKNOWN_PRIORITY = -1; 36 37 public FindUninitializedGet(BugReporter bugReporter) { 38 this.bugReporter = bugReporter; 39 } 40 41 42 43 @Override 44 public void visit(JavaClass obj) { 45 pendingBugs.clear(); 46 declaredFields.clear(); 47 super.visit(obj); 48 } 49 50 @Override 51 public void visit(Field obj) { 52 super.visit(obj); 53 FieldAnnotation f = FieldAnnotation.fromVisitedField(this); 54 declaredFields.add(f); 55 56 } 57 58 @Override 59 public void visit(Method obj) { 60 super.visit(obj); 61 initializedFields.clear(); 62 63 thisOnTOS = false; 64 inConstructor = getMethodName().equals("<init>") 65 && getMethodSig().indexOf(getClassName()) == -1; 66 67 } 68 69 70 @Override 71 public void visit(Code obj) { 72 super.visit(obj); 73 for(BugInstance bug : pendingBugs) { 74 bugReporter.reportBug(bug); 75 } 76 pendingBugs.clear(); 77 } 78 79 @Override 80 public void sawBranchTo(int target) { 81 Iterator<BugInstance> i = pendingBugs.iterator(); 82 while (i.hasNext()) { 83 BugInstance bug = i.next(); 84 if (bug.getPrimarySourceLineAnnotation().getStartBytecode()>= target) 85 i.remove(); 86 } 87 } 88 @Override 89 public void sawOpcode(int seen) { 90 if (!inConstructor) return; 91 92 if (seen == ALOAD_0) { 93 thisOnTOS = true; 94 97 return; 98 } 99 100 if (seen == PUTFIELD && getClassConstantOperand().equals(getClassName())) 101 initializedFields.add(FieldAnnotation.fromReferencedField(this)); 102 103 else if (thisOnTOS && seen == GETFIELD && getClassConstantOperand().equals(getClassName())) { 104 FieldAnnotation f = FieldAnnotation.fromReferencedField(this); 105 int nextOpcode = codeBytes[getPC() + 3]; 106 if (nextOpcode != POP && !initializedFields.contains(f) && declaredFields.contains(f)) { 108 pendingBugs.add(new BugInstance(this, "UR_UNINIT_READ", NORMAL_PRIORITY) 109 .addClassAndMethod(this) 110 .addField(f) 111 .addSourceLine(this)); 112 initializedFields.add(FieldAnnotation.fromReferencedField(this)); 113 } 114 } else if ( 115 (seen == INVOKESPECIAL 116 && !(getNameConstantOperand().equals("<init>") 117 && !getClassConstantOperand().equals(getClassName())) 118 ) 119 || (seen == INVOKESTATIC 120 && getNameConstantOperand().equals("doPrivileged") 121 && getClassConstantOperand().equals("java/security/AccessController") 122 ) 123 || (seen == INVOKEVIRTUAL 124 && getClassConstantOperand().equals(getClassName())) 125 || (seen == INVOKEVIRTUAL 126 && getNameConstantOperand().equals("start"))) { 127 128 inConstructor = false; 129 } 130 131 thisOnTOS = false; 132 } 133 } 134 | Popular Tags |