1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import java.util.Set ; 24 25 import edu.umd.cs.findbugs.*; 26 import edu.umd.cs.findbugs.ba.AnalysisContext; 27 import edu.umd.cs.findbugs.ba.ch.Subtypes; 28 29 import org.apache.bcel.classfile.*; 30 31 public class InheritanceUnsafeGetResource extends BytecodeScanningDetector implements StatelessDetector { 32 33 private BugReporter bugReporter; 34 private boolean classIsFinal; 35 private boolean classIsVisibleToOtherPackages; 37 private boolean methodIsStatic; 39 int state = 0; 40 int sawGetClass; 41 boolean reportedForThisClass; 42 String stringConstant; 43 int prevOpcode; 44 45 public InheritanceUnsafeGetResource(BugReporter bugReporter) { 46 this.bugReporter = bugReporter; 47 } 48 49 50 51 @Override 52 public void visit(JavaClass obj) { 53 classIsFinal = obj.isFinal(); 54 reportedForThisClass = false; 55 classIsVisibleToOtherPackages = obj.isPublic() || obj.isProtected(); 56 } 57 58 @Override 59 public void visit(Method obj) { 60 methodIsStatic = obj.isStatic(); 61 state = 0; 62 sawGetClass = -100; 63 } 64 65 @Override 66 public void sawOpcode(int seen) { 67 if (reportedForThisClass) return; 68 69 70 switch (seen) { 71 case LDC: 72 Constant constantValue = getConstantRefOperand(); 73 if (constantValue instanceof ConstantClass) 74 sawGetClass = -100; 75 else if (constantValue instanceof ConstantString) { 76 stringConstant = ((ConstantString)constantValue).getBytes(getConstantPool()); 77 } 78 break; 79 80 case ALOAD_0: 81 state = 1; 82 break; 83 case INVOKEVIRTUAL: 84 if (getClassConstantOperand().equals("java/lang/Class") 85 && (getNameConstantOperand().equals("getResource") 86 || getNameConstantOperand().equals("getResourceAsStream")) 87 && sawGetClass + 10 >= getPC()) { 88 Subtypes subtypes = AnalysisContext.currentAnalysisContext() 89 .getSubtypes(); 90 int priority = NORMAL_PRIORITY; 91 if (prevOpcode == LDC && stringConstant != null && stringConstant.charAt(0)=='/') 92 priority = LOW_PRIORITY; 93 else { 94 String myPackagename = getThisClass().getPackageName(); 95 Set <JavaClass> mySubtypes = subtypes.getTransitiveSubtypes(getThisClass()); 96 if (mySubtypes.isEmpty()) priority++; 97 else for(JavaClass c : mySubtypes) { 98 if (!c.getPackageName().equals(myPackagename)) { 99 priority--; 100 break; 101 } 102 } 103 } 104 bugReporter.reportBug(new BugInstance(this, "UI_INHERITANCE_UNSAFE_GETRESOURCE", 105 priority) 106 .addClassAndMethod(this) 107 .addSourceLine(this)); 108 reportedForThisClass = true; 109 110 } else if (state == 1 111 && !methodIsStatic 112 && !classIsFinal 113 && classIsVisibleToOtherPackages 114 && getNameConstantOperand().equals("getClass") 115 && getSigConstantOperand().equals("()Ljava/lang/Class;")) { 116 sawGetClass = getPC(); 117 } 118 state = 0; 119 break; 120 default: 121 state = 0; 122 break; 123 } 124 if (seen != LDC) stringConstant = null; 125 prevOpcode = seen; 126 127 } 128 129 } 130 | Popular Tags |