📄 findpuzzlers.java
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 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 org.apache.bcel.Repository;import org.apache.bcel.classfile.Code;import org.apache.bcel.classfile.JavaClass;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.OpcodeStack;import edu.umd.cs.findbugs.OpcodeStack.Item;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.XFactory;import edu.umd.cs.findbugs.ba.XMethod;import edu.umd.cs.findbugs.visitclass.Util;public class FindPuzzlers extends BytecodeScanningDetector { BugReporter bugReporter; public FindPuzzlers(BugReporter bugReporter) { this.bugReporter = bugReporter; } @Override public void visit(Code obj) { prevOpcodeIncrementedRegister = -1; best_priority_for_ICAST_INTEGER_MULTIPLY_CAST_TO_LONG = LOW_PRIORITY+1; prevOpCode = NOP; previousMethodInvocation = null; stack.resetForMethodEntry(this); badlyComputingOddState = 0; resetIMulCastLong(); imul_distance = 10000; ternaryConversionState = 0; super.visit(obj); } int imul_constant; int imul_distance; boolean imul_operand_is_parameter; int prevOpcodeIncrementedRegister; int valueOfConstantArgumentToShift; int best_priority_for_ICAST_INTEGER_MULTIPLY_CAST_TO_LONG ; boolean constantArgumentToShift; boolean shiftOfNonnegativeValue; int ternaryConversionState = 0; int badlyComputingOddState; int prevOpCode; XMethod previousMethodInvocation; OpcodeStack stack = new OpcodeStack(); boolean isTigerOrHigher; @Override public void visit(JavaClass obj) { isTigerOrHigher = obj.getMajor() >= MAJOR_1_5; } private void resetIMulCastLong() { imul_constant = 1; imul_operand_is_parameter = false; } private int adjustPriority(int factor, int priority) { if (factor <= 4) return LOW_PRIORITY+2; if (factor <= 10000) return priority+1; if (factor <= 60*60*1000) return priority; return priority-1; } private int adjustMultiplier(Object constant, int mul) { if (!(constant instanceof Integer)) return mul; return Math.abs(((Integer) constant).intValue()) * mul; } @Override public void sawOpcode(int seen) { stack.mergeJumps(this); // System.out.println(getPC() + " " + OPCODE_NAMES[seen] + " " + ternaryConversionState); if (seen == IMUL) { if (imul_distance != 1) resetIMulCastLong(); imul_distance = 0; if (stack.getStackDepth() > 1) { OpcodeStack.Item item0 = stack.getStackItem(0); OpcodeStack.Item item1 = stack.getStackItem(1); imul_constant = adjustMultiplier(item0.getConstant(), imul_constant); imul_constant = adjustMultiplier(item1.getConstant(), imul_constant); if (item0.isInitialParameter() || item1.isInitialParameter()) imul_operand_is_parameter = true; }} else { imul_distance++; } if (prevOpCode == IMUL && seen == I2L) { int priority = adjustPriority(imul_constant, NORMAL_PRIORITY); if (priority >= LOW_PRIORITY && imul_operand_is_parameter) priority = NORMAL_PRIORITY; if (priority <= best_priority_for_ICAST_INTEGER_MULTIPLY_CAST_TO_LONG) { best_priority_for_ICAST_INTEGER_MULTIPLY_CAST_TO_LONG = priority; bugReporter.reportBug(new BugInstance(this, "ICAST_INTEGER_MULTIPLY_CAST_TO_LONG", priority) .addClassAndMethod(this) .addSourceLine(this)); } } if (getMethodName().equals("<clinit>") && (seen == PUTSTATIC || seen == GETSTATIC || seen == INVOKESTATIC)) { String clazz = getClassConstantOperand(); if (!clazz.equals(getClassName())) { try { JavaClass targetClass = Repository.lookupClass(clazz); if (Repository.instanceOf(targetClass, getThisClass())) { int priority = NORMAL_PRIORITY; if (seen == GETSTATIC) priority--; if (!targetClass.isPublic()) priority++; bugReporter.reportBug(new BugInstance(this, "IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION", priority) .addClassAndMethod(this).addClass(getDottedClassConstantOperand()) .addSourceLine(this) ); } } catch (ClassNotFoundException e) { // ignore it } } } if (false && (seen == INVOKEVIRTUAL) && getNameConstantOperand().equals("equals") && getSigConstantOperand().equals("(Ljava/lang/Object;)Z") && stack.getStackDepth() > 1) { OpcodeStack.Item item0 = stack.getStackItem(0); OpcodeStack.Item item1 = stack.getStackItem(1); if (item0.isArray() || item1.isArray()) { bugReporter.reportBug(new BugInstance("EC_BAD_ARRAY_COMPARE", NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } } if (seen >= IALOAD && seen <= SALOAD || seen >= IASTORE && seen <= SASTORE ) { Item index = stack.getStackItem(0); if (index.getSpecialKind() == Item.AVERAGE_COMPUTED_USING_DIVISION) bugReporter.reportBug(new BugInstance(this, "IM_AVERAGE_COMPUTATION_COULD_OVERFLOW", NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } if ((seen == IFEQ || seen == IFNE) && getPrevOpcode(1) == IMUL && ( getPrevOpcode(2) == SIPUSH || getPrevOpcode(2) == BIPUSH ) && getPrevOpcode(3) == IREM ) bugReporter.reportBug(new BugInstance(this, "IM_MULTIPLYING_RESULT_OF_IREM", LOW_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); if (seen == I2S && getPrevOpcode(1) == IUSHR && !shiftOfNonnegativeValue && (!constantArgumentToShift || valueOfConstantArgumentToShift % 16 != 0) || seen == I2B && getPrevOpcode(1) == IUSHR && !shiftOfNonnegativeValue && (!constantArgumentToShift || valueOfConstantArgumentToShift % 8 != 0)) bugReporter.reportBug(new BugInstance(this, "ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT", NORMAL_PRIORITY) .addClassAndMethod(this).addSourceLine(this)); constantArgumentToShift = false; shiftOfNonnegativeValue = false; if ( (seen == IUSHR || seen == ISHR || seen == ISHL )) { if (stack.getStackDepth() <= 1) { // don't understand; lie so other detectors won't get concerned constantArgumentToShift = true; valueOfConstantArgumentToShift = 8; } else { Object rightHandSide = stack.getStackItem(0).getConstant(); Object leftHandSide = stack.getStackItem(1).getConstant(); shiftOfNonnegativeValue = stack.getStackItem(1).isNonNegative(); if (rightHandSide instanceof Integer) { constantArgumentToShift = true; valueOfConstantArgumentToShift = ((Integer) rightHandSide); if (valueOfConstantArgumentToShift < 0 || valueOfConstantArgumentToShift >= 32) bugReporter.reportBug(new BugInstance(this, "ICAST_BAD_SHIFT_AMOUNT", valueOfConstantArgumentToShift < 0 ? LOW_PRIORITY : HIGH_PRIORITY)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -