1 package edu.umd.cs.findbugs.detect; 2 3 import java.io.File ; 4 import java.util.Iterator ; 5 6 import org.apache.bcel.classfile.Method; 7 import org.apache.bcel.generic.ConstantPoolGen; 8 import org.apache.bcel.generic.Instruction; 9 import org.apache.bcel.generic.InvokeInstruction; 10 import org.apache.bcel.generic.MethodGen; 11 12 import edu.umd.cs.findbugs.BugInstance; 13 import edu.umd.cs.findbugs.BugReporter; 14 import edu.umd.cs.findbugs.Detector; 15 import edu.umd.cs.findbugs.SourceLineAnnotation; 16 import edu.umd.cs.findbugs.SystemProperties; 17 import edu.umd.cs.findbugs.ba.CFG; 18 import edu.umd.cs.findbugs.ba.CFGBuilderException; 19 import edu.umd.cs.findbugs.ba.ClassContext; 20 import edu.umd.cs.findbugs.ba.DataflowAnalysisException; 21 import edu.umd.cs.findbugs.ba.Location; 22 import edu.umd.cs.findbugs.ba.MethodUnprofitableException; 23 import edu.umd.cs.findbugs.ba.constant.Constant; 24 import edu.umd.cs.findbugs.ba.constant.ConstantDataflow; 25 import edu.umd.cs.findbugs.ba.constant.ConstantFrame; 26 27 public class DumbMethodInvocations implements Detector { 28 29 private BugReporter bugReporter; 30 31 public DumbMethodInvocations(BugReporter bugReporter) { 32 this.bugReporter = bugReporter; 33 } 34 35 public void visitClassContext(ClassContext classContext) { 36 Method[] methodList = classContext.getJavaClass().getMethods(); 37 38 for (Method method : methodList) { 39 if (method.getCode() == null) 40 continue; 41 42 try { 43 analyzeMethod(classContext, method); 44 } catch (MethodUnprofitableException mue) { 45 if (SystemProperties.getBoolean("unprofitable.debug")) bugReporter.logError("skipping unprofitable method in " + getClass().getName()); 47 } catch (CFGBuilderException e) { 48 bugReporter.logError("Detector " + this.getClass().getName() 49 + " caught exception", e); 50 } catch (DataflowAnalysisException e) { 51 bugReporter.logError("Detector " + this.getClass().getName() 52 + " caught exception", e); 53 } 54 } 55 } 56 57 private void analyzeMethod(ClassContext classContext, Method method) 58 throws CFGBuilderException, DataflowAnalysisException { 59 CFG cfg = classContext.getCFG(method); 60 ConstantDataflow constantDataflow = classContext 61 .getConstantDataflow(method); 62 ConstantPoolGen cpg = classContext.getConstantPoolGen(); 63 MethodGen methodGen = classContext.getMethodGen(method); 64 String sourceFile = classContext.getJavaClass().getSourceFileName(); 65 66 for (Iterator <Location> i = cfg.locationIterator(); i.hasNext();) { 67 Location location = i.next(); 68 69 Instruction ins = location.getHandle().getInstruction(); 70 if (!(ins instanceof InvokeInstruction)) 71 continue; 72 InvokeInstruction iins = (InvokeInstruction) ins; 73 74 ConstantFrame frame = constantDataflow.getFactAtLocation(location); 75 if (!frame.isValid()) { 76 continue; 78 } 79 80 if (iins.getName(cpg).equals("substring") 81 && iins.getSignature(cpg).equals("(I)Ljava/lang/String;") 82 && iins.getClassName(cpg).equals("java.lang.String")) { 83 84 Constant operandValue = frame.getTopValue(); 85 if (!operandValue.isConstantInteger()) 86 continue; 87 int v = operandValue.getConstantInt(); 88 if (v == 0) 89 bugReporter.reportBug(new BugInstance(this, 90 "DMI_USELESS_SUBSTRING", NORMAL_PRIORITY) 91 .addClassAndMethod(methodGen, sourceFile) 92 .addSourceLine( 93 SourceLineAnnotation 94 .fromVisitedInstruction(classContext, methodGen, 95 sourceFile, location 96 .getHandle()))); 97 98 } 99 else 100 if (iins.getName(cpg).equals("<init>") 101 && iins.getSignature(cpg).equals("(Ljava/lang/String;)V") 102 && iins.getClassName(cpg).equals("java.io.File")) { 103 104 Constant operandValue = frame.getTopValue(); 105 if (!operandValue.isConstantString()) 106 continue; 107 String v = operandValue.getConstantString(); 108 if (isAbsoluteFileName(v)) 109 bugReporter.reportBug(new BugInstance(this, 110 "DMI_HARDCODED_ABSOLUTE_FILENAME", v.startsWith("/tmp") ? LOW_PRIORITY : NORMAL_PRIORITY) 111 .addClassAndMethod(methodGen, sourceFile) 112 .addString(v).describe("FILE_NAME") 113 .addSourceLine( 114 SourceLineAnnotation 115 .fromVisitedInstruction(classContext, methodGen, 116 sourceFile, location 117 .getHandle()))); 118 119 } 120 121 } 122 } 123 124 private boolean isAbsoluteFileName(String v) { 125 if (v.startsWith("/dev/")) return false; 126 if (v.startsWith("/")) return true; 127 if (v.startsWith("C:")) return true; 128 if (v.startsWith("c:")) return true; 129 try { 130 File f = new File (v); 131 return f.isAbsolute(); 132 } catch (RuntimeException e) { 133 return false; 134 } 135 } 136 137 public void report() { 138 } 139 140 } 141 | Popular Tags |