📄 dumbmethods.java
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-2005 University of Maryland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package edu.umd.cs.findbugs.detect;import java.util.HashSet;import java.util.Iterator;import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;import org.apache.bcel.classfile.Attribute;import org.apache.bcel.classfile.Code;import org.apache.bcel.classfile.CodeException;import org.apache.bcel.classfile.Constant;import org.apache.bcel.classfile.ConstantClass;import org.apache.bcel.classfile.ConstantPool;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.classfile.Synthetic;import org.apache.bcel.generic.ObjectType;import org.apache.bcel.generic.ReferenceType;import org.apache.bcel.generic.Type;import edu.umd.cs.findbugs.BugAccumulator;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.BytecodeScanningDetector;import edu.umd.cs.findbugs.IntAnnotation;import edu.umd.cs.findbugs.JavaVersion;import edu.umd.cs.findbugs.OpcodeStack;import edu.umd.cs.findbugs.SourceLineAnnotation;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.CFGBuilderException;import edu.umd.cs.findbugs.ba.DataflowAnalysisException;import edu.umd.cs.findbugs.ba.Hierarchy;import edu.umd.cs.findbugs.ba.ObjectTypeFactory;import edu.umd.cs.findbugs.ba.SignatureParser;import edu.umd.cs.findbugs.ba.type.TypeDataflow;public class DumbMethods extends BytecodeScanningDetector { private static final ObjectType CONDITION_TYPE = ObjectTypeFactory.getInstance("java.util.concurrent.locks.Condition"); private HashSet<String> alreadyReported = new HashSet<String>(); private BugReporter bugReporter; private boolean sawCurrentTimeMillis; private BugInstance gcInvocationBugReport; private int gcInvocationPC; private CodeException[] exceptionTable;/* private boolean sawLDCEmptyString;*/ private String primitiveObjCtorSeen; private boolean ctorSeen; private boolean prevOpcodeWasReadLine; private int prevOpcode; private boolean isPublicStaticVoidMain; private boolean isEqualsObject; private boolean sawInstanceofCheck; private boolean reportedBadCastInEquals; private int sinceBufferedInputStreamReady; private int randomNextIntState; private boolean checkForBitIorofSignedByte; private boolean jdk15ChecksEnabled; private BugAccumulator accumulator; public DumbMethods(BugReporter bugReporter) { this.bugReporter = bugReporter; accumulator = new BugAccumulator(bugReporter); jdk15ChecksEnabled = JavaVersion.getRuntimeVersion().isSameOrNewerThan(JavaVersion.JAVA_1_5); } OpcodeStack stack = new OpcodeStack(); boolean isSynthetic; @Override public void visit(JavaClass obj) { String superclassName = obj.getSuperclassName(); isSynthetic = superclassName.equals("java.rmi.server.RemoteStub"); Attribute[] attributes = obj.getAttributes(); if (attributes != null) for(Attribute a : attributes) if (a instanceof Synthetic) isSynthetic = true; } @Override public void visitAfter(JavaClass obj) { accumulator.reportAccumulatedBugs(); } public static boolean isTestMethod(Method method) { return method.getName().startsWith("test"); } @Override public void visit(Method method) { String cName = getDottedClassName(); stack.resetForMethodEntry(this); isPublicStaticVoidMain = method.isPublic() && method.isStatic() && getMethodName().equals("main") || cName.toLowerCase().indexOf("benchmark") >= 0; prevOpcodeWasReadLine = false; Code code = method.getCode(); if (code != null) this.exceptionTable = code.getExceptionTable(); if (this.exceptionTable == null) this.exceptionTable = new CodeException[0]; primitiveObjCtorSeen = null; ctorSeen = false; randomNextIntState = 0; checkForBitIorofSignedByte = false; isEqualsObject = getMethodName().equals("equals") && getMethodSig().equals("(Ljava/lang/Object;)Z") && !method.isStatic(); sawInstanceofCheck = false; reportedBadCastInEquals = false; freshRandomOnTos = false; sinceBufferedInputStreamReady = 100000; } boolean freshRandomOnTos = false; boolean freshRandomOneBelowTos = false; @Override public void sawOpcode(int seen) { stack.mergeJumps(this); String opcodeName = OPCODE_NAMES[seen]; if ((seen == INVOKESTATIC || seen == INVOKEVIRTUAL || seen == INVOKESPECIAL || seen == INVOKEINTERFACE) && getSigConstantOperand().indexOf("Ljava/lang/Runnable;") >= 0) { SignatureParser parser = new SignatureParser(getSigConstantOperand()); int count = 0; for(Iterator<String> i = parser.parameterSignatureIterator(); i.hasNext(); count++) { String parameter = i.next(); if (parameter.equals("Ljava/lang/Runnable;")) { OpcodeStack.Item item = stack.getStackItem(parser.getSlotsFromTopOfStackForParameter(count)); if ("Ljava/lang/Thread;".equals(item.getSignature())) bugReporter.reportBug(new BugInstance(this, "DMI_THREAD_PASSED_WHERE_RUNNABLE_EXPECTED", NORMAL_PRIORITY) .addClassAndMethod(this) .addCalledMethod(this) .addSourceLine(this)); } } } if (prevOpcode == I2L && seen == INVOKESTATIC && getClassConstantOperand().equals("java/lang/Double") && getNameConstantOperand() .equals("longBitsToDouble")) bugReporter.reportBug(new BugInstance(this, "DMI_LONG_BITS_TO_DOUBLE_INVOKED_ON_INT", HIGH_PRIORITY) .addClassAndMethod(this) .addCalledMethod(this) .addSourceLine(this)); if (freshRandomOnTos && seen == INVOKEVIRTUAL || freshRandomOneBelowTos && seen == INVOKEVIRTUAL && getClassConstantOperand().equals("java/util/Random") ) { bugReporter.reportBug(new BugInstance(this, "DMI_RANDOM_USED_ONLY_ONCE", HIGH_PRIORITY) .addClassAndMethod(this) .addCalledMethod(this) .addSourceLine(this)); } freshRandomOneBelowTos = freshRandomOnTos && isRegisterLoad(); freshRandomOnTos = seen == INVOKESPECIAL && getClassConstantOperand().equals("java/util/Random") && getNameConstantOperand().equals("<init>"); if ((seen == INVOKEVIRTUAL && getClassConstantOperand().equals("java/util/HashMap") && getNameConstantOperand() .equals("get")) || (seen == INVOKEINTERFACE && getClassConstantOperand().equals("java/util/Map") && getNameConstantOperand() .equals("get")) || (seen == INVOKEVIRTUAL && getClassConstantOperand() .equals("java/util/HashSet") && getNameConstantOperand() .equals("contains")) || (seen == INVOKEINTERFACE && getClassConstantOperand().equals("java/util/Set") && getNameConstantOperand() .equals("contains"))) { OpcodeStack.Item top = stack.getStackItem(0); if (top.getSignature().equals("Ljava/net/URL;")) bugReporter.reportBug(new BugInstance(this, "DMI_COLLECTION_OF_URLS", HIGH_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } if (isEqualsObject && !reportedBadCastInEquals) { if (seen == INSTANCEOF || seen == INVOKEVIRTUAL && getNameConstantOperand().equals("getClass") && getSigConstantOperand().equals("()Ljava/lang/Class;") ) { OpcodeStack.Item item = stack.getStackItem(0); if (item.getRegisterNumber() == 1) sawInstanceofCheck = true; } else if (seen == INVOKESPECIAL && getNameConstantOperand().equals("equals") && getSigConstantOperand().equals("(Ljava/lang/Object;)Z")) { OpcodeStack.Item item0 = stack.getStackItem(0); OpcodeStack.Item item1 = stack.getStackItem(1); if (item1.getRegisterNumber() + item0.getRegisterNumber() == 1) sawInstanceofCheck = true; } else if (seen == CHECKCAST && !sawInstanceofCheck) { OpcodeStack.Item item = stack.getStackItem(0); if (item.getRegisterNumber() == 1) { if (getSizeOfSurroundingTryBlock(getPC()) == Integer.MAX_VALUE) bugReporter.reportBug(new BugInstance(this, "BC_EQUALS_METHOD_SHOULD_WORK_FOR_ALL_OBJECTS", NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); reportedBadCastInEquals = true; } } } { boolean foundVacuousComparison = false; if (seen == IF_ICMPGT || seen == IF_ICMPLE) { OpcodeStack.Item rhs = stack.getStackItem(0); Object rhsConstant = rhs.getConstant(); if (rhsConstant instanceof Integer && ((Integer)rhsConstant).intValue() == Integer.MAX_VALUE) foundVacuousComparison = true; OpcodeStack.Item lhs = stack.getStackItem(1); Object lhsConstant = lhs.getConstant(); if (lhsConstant instanceof Integer && ((Integer)lhsConstant).intValue() == Integer.MIN_VALUE) foundVacuousComparison = true; } if (seen == IF_ICMPLT || seen == IF_ICMPGE) { OpcodeStack.Item rhs = stack.getStackItem(0); Object rhsConstant = rhs.getConstant(); if (rhsConstant instanceof Integer && ((Integer)rhsConstant).intValue() == Integer.MIN_VALUE) foundVacuousComparison = true; OpcodeStack.Item lhs = stack.getStackItem(1); Object lhsConstant = lhs.getConstant(); if (lhsConstant instanceof Integer && ((Integer)lhsConstant).intValue() == Integer.MAX_VALUE) foundVacuousComparison = true; } if (foundVacuousComparison) bugReporter.reportBug(new BugInstance(this, "INT_VACUOUS_COMPARISON", getBranchOffset() < 0 ? HIGH_PRIORITY : NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } if (seen == INVOKESTATIC && ( getClassConstantOperand().equals("java/lang/Math") || getClassConstantOperand().equals("java/lang/StrictMath")) && getNameConstantOperand().equals("abs") && getSigConstantOperand().equals("(I)I")) { OpcodeStack.Item item0 = stack.getStackItem(0); int special = item0.getSpecialKind(); if (special == OpcodeStack.Item.RANDOM_INT) bugReporter.reportBug(new BugInstance(this, "RV_ABSOLUTE_VALUE_OF_RANDOM_INT", HIGH_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); else if (special == OpcodeStack.Item.HASHCODE_INT) bugReporter.reportBug(new BugInstance(this, "RV_ABSOLUTE_VALUE_OF_HASHCODE", HIGH_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } try { int stackLoc = stackEntryThatMustBeNonnegative(seen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -