1 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import java.util.regex.Pattern ; 25 import org.apache.bcel.classfile.Code; 26 27 36 37 public class VarArgsProblems extends BytecodeScanningDetector implements 38 StatelessDetector { 39 40 private BugReporter bugReporter; 41 42 private int state; 43 44 public VarArgsProblems(BugReporter bugReporter) { 45 this.bugReporter = bugReporter; 46 } 47 48 49 50 @Override 51 public void visitCode(Code obj) { 52 state = SEEN_NOTHING; 53 super.visitCode(obj); 54 } 55 56 public static final int SEEN_NOTHING = 0; 57 58 public static final int SEEN_ICONST_1 = 1; 59 60 public static final int SEEN_ANEWARRAY = 2; 61 62 public static final int SEEN_DUP = 3; 63 64 public static final int SEEN_ICONST_0 = 4; 65 66 public static final int SEEN_ALOAD = 5; 67 68 public static final int SEEN_AASTORE = 6; 69 70 public static final int SEEN_GOTO = 7; 71 72 Pattern primitiveArray = Pattern.compile("\\[[IJDFSCB]"); 73 String primitiveArraySig; 74 @Override 75 public void sawOpcode( int seen) { 76 if (seen == GOTO && getBranchOffset() == 4) { 78 state = SEEN_GOTO; 79 } else 80 switch (state) { 81 case SEEN_NOTHING: 82 if ((seen == ICONST_1)) 83 state = SEEN_ICONST_1; 84 break; 85 86 case SEEN_ICONST_1: 87 if (seen == ANEWARRAY && primitiveArray.matcher(getClassConstantOperand()).matches()) { 88 primitiveArraySig = getClassConstantOperand(); 90 state = SEEN_ANEWARRAY; 91 } 92 else 93 state = SEEN_NOTHING; 94 break; 95 96 case SEEN_ANEWARRAY: 97 if (seen == DUP) 98 state = SEEN_DUP; 99 else 100 state = SEEN_NOTHING; 101 break; 102 case SEEN_DUP: 103 if (seen == ICONST_0) 104 state = SEEN_ICONST_0; 105 else 106 state = SEEN_NOTHING; 107 break; 108 case SEEN_ICONST_0: 109 if (((seen >= ALOAD_0) && (seen < ALOAD_3)) || (seen == ALOAD)) 110 state = SEEN_ALOAD; 111 else 112 state = SEEN_NOTHING; 113 break; 114 115 case SEEN_ALOAD: 116 if (seen == AASTORE) 117 state = SEEN_AASTORE; 118 else 119 state = SEEN_NOTHING; 120 break; 121 122 case SEEN_AASTORE: 123 if (seen == INVOKESTATIC || seen == INVOKEINTERFACE 124 || seen == INVOKESPECIAL || seen == INVOKEVIRTUAL) { 125 if (getSigConstantOperand().indexOf("Ljava/lang/Object;)") == -1) break; 129 int priority = NORMAL_PRIORITY; 130 if (getNameConstantOperand().equals("asList") 131 && getClassConstantOperand().equals("java/util/Arrays")) 132 priority = HIGH_PRIORITY; 133 bugReporter.reportBug( new BugInstance( this, "VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG", priority) 134 .addClassAndMethod(this) 135 .addType(primitiveArraySig) 136 .addCalledMethod(this) 137 .addSourceLine(this)); 138 } 139 state = SEEN_NOTHING; 140 break; 141 142 case SEEN_GOTO: 143 state = SEEN_NOTHING; 144 break; 145 default: 146 throw new IllegalStateException ("State " + state 147 + " not expected"); 148 149 } 150 } 151 } 152 | Popular Tags |