1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import org.apache.bcel.classfile.*; 25 26 public class FindReturnRef extends BytecodeScanningDetector { 27 boolean check = false; 28 boolean thisOnTOS = false; 29 boolean fieldOnTOS = false; 30 boolean publicClass = false; 31 boolean staticMethod = false; 32 boolean dangerousToStoreIntoField = false; 33 String nameOnStack; 34 String classNameOnStack; 35 String sigOnStack; 36 int parameterCount; 37 int timesRead [] = new int[256]; 39 boolean fieldIsStatic; 40 private BugReporter bugReporter; 41 43 public FindReturnRef(BugReporter bugReporter) { 44 this.bugReporter = bugReporter; 45 } 46 47 @Override 48 public void visit(JavaClass obj) { 49 publicClass = obj.isPublic(); 50 super.visit(obj); 51 } 52 53 @Override 54 public void visit(Method obj) { 55 check = publicClass && (obj.getAccessFlags() & (ACC_PUBLIC)) != 0; 56 if (!check) return; 57 dangerousToStoreIntoField = false; 58 staticMethod = (obj.getAccessFlags() & (ACC_STATIC)) != 0; 59 parameterCount = getNumberMethodArguments(); 61 66 67 if (!staticMethod) parameterCount++; 68 69 for (int i = 0; i < parameterCount; i++) 70 timesRead[i] = 0; 71 thisOnTOS = false; 72 fieldOnTOS = false; 73 super.visit(obj); 74 thisOnTOS = false; 75 fieldOnTOS = false; 76 } 77 78 79 @Override 80 public void visit(Code obj) { 81 if (check) super.visit(obj); 82 } 83 84 @Override 85 public void sawOpcode(int seen) { 86 assert check; 87 94 95 if (staticMethod && dangerousToStoreIntoField && seen == PUTSTATIC 96 && MutableStaticFields.mutableSignature(getSigConstantOperand())) { 97 bugReporter.reportBug(new BugInstance(this, "EI_EXPOSE_STATIC_REP2", NORMAL_PRIORITY) 98 .addClassAndMethod(this) 99 .addField(getDottedClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand(), 100 true) 101 .addSourceLine(this)); 102 } 103 if (!staticMethod && dangerousToStoreIntoField && seen == PUTFIELD 104 && MutableStaticFields.mutableSignature(getSigConstantOperand())) { 105 bugReporter.reportBug(new BugInstance(this, "EI_EXPOSE_REP2", NORMAL_PRIORITY) 106 .addClassAndMethod(this) 107 .addField(getDottedClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand(), 108 true) 109 .addSourceLine(this)); 110 121 } 122 dangerousToStoreIntoField = false; 123 int reg = -1; checkStore: { 125 switch (seen) { 126 case ALOAD_0: 127 reg = 0; 128 break; 129 case ALOAD_1: 130 reg = 1; 131 break; 132 case ALOAD_2: 133 reg = 2; 134 break; 135 case ALOAD_3: 136 reg = 3; 137 break; 138 case ALOAD: 139 reg = getRegisterOperand(); 140 break; 141 default: 142 break checkStore; 143 } 144 if (reg < parameterCount) 145 timesRead[reg]++; 146 } 147 if (thisOnTOS && !staticMethod) { 148 switch (seen) { 149 case ALOAD_1: 150 case ALOAD_2: 151 case ALOAD_3: 152 case ALOAD: 153 if (reg < parameterCount) { 154 dangerousToStoreIntoField = true; 156 } 158 default: 159 } 160 } else if (staticMethod) { 161 switch (seen) { 162 case ALOAD_0: 163 case ALOAD_1: 164 case ALOAD_2: 165 case ALOAD_3: 166 case ALOAD: 167 if (reg < parameterCount) { 168 dangerousToStoreIntoField = true; 170 } 171 default: 172 } 173 } 174 175 if (seen == ALOAD_0 && !staticMethod) { 176 thisOnTOS = true; 177 fieldOnTOS = false; 178 return; 179 } 180 181 182 if (thisOnTOS && seen == GETFIELD && getClassConstantOperand().equals(getClassName())) { 183 fieldOnTOS = true; 184 thisOnTOS = false; 185 nameOnStack = getNameConstantOperand(); 186 classNameOnStack = getDottedClassConstantOperand(); 187 sigOnStack = getSigConstantOperand(); 188 fieldIsStatic = false; 189 return; 191 } 192 if (seen == GETSTATIC && getClassConstantOperand().equals(getClassName())) { 193 fieldOnTOS = true; 194 thisOnTOS = false; 195 nameOnStack = getNameConstantOperand(); 196 classNameOnStack = getDottedClassConstantOperand(); 197 sigOnStack = getSigConstantOperand(); 198 fieldIsStatic = true; 199 return; 200 } 201 thisOnTOS = false; 202 if (check && fieldOnTOS && seen == ARETURN 203 208 && nameOnStack.indexOf("EMPTY") == -1 209 && MutableStaticFields.mutableSignature(sigOnStack) 210 ) { 211 bugReporter.reportBug(new BugInstance(this, staticMethod ? "MS_EXPOSE_REP" : "EI_EXPOSE_REP", NORMAL_PRIORITY) 212 .addClassAndMethod(this) 213 .addField(classNameOnStack, nameOnStack, sigOnStack, fieldIsStatic) 214 .addSourceLine(this)); 215 } 216 217 fieldOnTOS = false; 218 thisOnTOS = false; 219 } 220 221 222 } 223 | Popular Tags |