src.main.java.com.mebigfatguy.fbcontrib.detect.CompareClassNameEquals Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fb-contrib Show documentation
Show all versions of fb-contrib Show documentation
An auxiliary findbugs.sourceforge.net plugin for java bug detectors that fall outside the narrow scope of detectors to be packaged with the product itself.
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2018 Bhaskar Maddala
* Copyright (C) 2005-2018 Dave Brosius
*
* 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 com.mebigfatguy.fbcontrib.detect;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.LocalVariableTable;
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.SignatureBuilder;
import com.mebigfatguy.fbcontrib.utils.Values;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.OpcodeStack.CustomUserValue;
import edu.umd.cs.findbugs.OpcodeStack.Item;
import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;
/**
* In a JVM, Two classes are the same class (and consequently the same type) if they are loaded by the same class loader, and they have the same fully qualified
* name [JVMSpec 1999].
*
* Two classes with the same name but different package names are distinct, as are two classes with the same fully qualified name loaded by different class
* loaders.
*
* Find usage involving comparison of class names, rather than the class itself.
*
*/
@CustomUserValue
public class CompareClassNameEquals extends OpcodeStackDetector {
private boolean flag = false;
private final BugReporter bugReporter;
public CompareClassNameEquals(final BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
@Override
public boolean shouldVisitCode(Code obj) {
flag = false;
LocalVariableTable lvt = getMethod().getLocalVariableTable();
return lvt != null;
}
@Override
public void afterOpcode(int seen) {
super.afterOpcode(seen);
if (flag) {
stack.getStackItem(0).setUserValue(Boolean.TRUE);
flag = false;
}
}
@Override
public void sawOpcode(int seen) {
if (seen == INVOKEVIRTUAL) {
if ("getName".equals(getNameConstantOperand()) && SignatureBuilder.SIG_VOID_TO_STRING.equals(getSigConstantOperand())
&& Values.SLASHED_JAVA_LANG_CLASS.equals(getClassConstantOperand())) {
flag = true;
} else if ("equals".equals(getNameConstantOperand()) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(getSigConstantOperand())
&& Values.SLASHED_JAVA_LANG_STRING.equals(getClassConstantOperand())) {
Item item = stack.getItemMethodInvokedOn(this);
Object srcValue = item.getUserValue();
item = stack.getStackItem(0);
Object dstValue = item.getUserValue();
if (Boolean.TRUE.equals(srcValue) && Boolean.TRUE.equals(dstValue)) {
bugReporter.reportBug(new BugInstance(this, BugType.CCNE_COMPARE_CLASS_EQUALS_NAME.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
.addSourceLine(this));
}
}
}
}
}