use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class ListIndexedIterating method sawOpcodeBug.
/**
* the second pass to look for get methods on the for loop reg
*
* @param seen
* the currently parsed opcode
*/
private void sawOpcodeBug(final int seen) {
try {
stack.precomputation(this);
Iterator<ForLoop> it = possibleForLoops.iterator();
while (it.hasNext()) {
ForLoop fl = it.next();
switch(fl.getLoopState()) {
case LOOP_NOT_STARTED:
if (getPC() == fl.getLoopStart()) {
if (OpcodeUtils.isILoad(seen) && (RegisterUtils.getLoadReg(this, seen) == fl.getLoopReg())) {
fl.setLoopState(LoopState.LOOP_INDEX_LOADED_FOR_TEST);
continue;
}
it.remove();
}
break;
case LOOP_INDEX_LOADED_FOR_TEST:
if (getPC() >= fl.getLoopEnd()) {
it.remove();
continue;
}
if (seen == Const.IF_ICMPGE) {
if (stack.getStackDepth() > 1) {
OpcodeStack.Item itm = stack.getStackItem(0);
if (itm.getConstant() != null) {
it.remove();
continue;
}
XMethod constantSource = itm.getReturnValueOf();
if (constantSource != null) {
if (!"size".equals(constantSource.getMethodDescriptor().getName())) {
it.remove();
continue;
}
} else if (getPrevOpcode(1) != Const.ARRAYLENGTH) {
it.remove();
continue;
}
}
int branchTarget = getBranchTarget();
if ((branchTarget >= (fl.getLoopEnd() + 3)) && (branchTarget <= (fl.getLoopEnd() + 5))) {
fl.setLoopState(LoopState.LOOP_IN_BODY);
continue;
}
}
break;
case LOOP_IN_BODY:
case LOOP_IN_BODY_WITH_GET:
if ((getPC() == fl.getLoopEnd()) && (fl.getLoopState() == LoopState.LOOP_IN_BODY_WITH_GET)) {
bugReporter.reportBug(new BugInstance(this, "LII_LIST_INDEXED_ITERATING", NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLineRange(this, fl.getLoopStart(), fl.getLoopEnd()));
it.remove();
}
if (getPC() > fl.getLoopEnd()) {
it.remove();
}
if (OpcodeUtils.isILoad(seen)) {
loopReg = RegisterUtils.getLoadReg(this, seen);
if (loopReg == fl.getLoopReg()) {
fl.setLoopRegLoaded(true);
}
} else if (fl.getLoopRegLoaded()) {
boolean sawGet = ((seen == Const.INVOKEINTERFACE) && Values.SLASHED_JAVA_UTIL_LIST.equals(getClassConstantOperand()) && "get".equals(getNameConstantOperand()) && SignatureBuilder.SIG_INT_TO_OBJECT.equals(getSigConstantOperand()));
if (!sawGet) {
it.remove();
} else {
fl.setLoopState(LoopState.LOOP_IN_BODY_WITH_GET);
if (stack.getStackDepth() > 1) {
OpcodeStack.Item itm = stack.getStackItem(0);
if (!itm.couldBeZero()) {
it.remove();
} else {
itm = stack.getStackItem(1);
if (fl.isSecondItem(itm)) {
it.remove();
}
}
}
fl.setLoopRegLoaded(false);
}
}
break;
}
}
} finally {
stack.sawOpcode(this, seen);
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class LiteralStringComparison method sawOpcode.
/**
* looks for strings comparisons where the stack object is a literal
*
* @param seen
* the currently parsed opcode
*/
@Override
public void sawOpcode(final int seen) {
Object hashCodedStringRef = null;
try {
stack.precomputation(this);
switch(seen) {
case INVOKEVIRTUAL:
if (Values.SLASHED_JAVA_LANG_STRING.equals(getClassConstantOperand())) {
String calledMethodName = getNameConstantOperand();
String calledMethodSig = getSigConstantOperand();
if (("equals".equals(calledMethodName) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(calledMethodSig)) || ("compareTo".equals(calledMethodName) && SignatureBuilder.SIG_STRING_TO_INT.equals(calledMethodSig)) || ("equalsIgnoreCase".equals(calledMethodName) && SignatureBuilder.SIG_STRING_TO_BOOLEAN.equals(calledMethodSig))) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item itm = stack.getStackItem(0);
Object constant = itm.getConstant();
if ((constant != null) && constant.getClass().equals(String.class) && !lookupSwitchOnString()) {
bugReporter.reportBug(// very
new BugInstance(this, "LSC_LITERAL_STRING_COMPARISON", HIGH_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
} else if (Values.HASHCODE.equals(calledMethodName) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
int reg = item.getRegisterNumber();
if (reg >= 0) {
hashCodedStringRef = String.valueOf(reg);
} else {
XField xf = item.getXField();
if (xf != null) {
hashCodedStringRef = xf.getName();
} else {
XMethod xm = item.getReturnValueOf();
if (xm != null) {
hashCodedStringRef = xm.toString();
}
}
}
}
}
break;
case LOOKUPSWITCH:
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
String stringRef = (String) item.getUserValue();
if (stringRef != null) {
int[] offsets = getSwitchOffsets();
BitSet bs = new BitSet();
int pc = getPC();
for (int offset : offsets) {
bs.set(pc + offset);
}
bs.set(pc + getDefaultSwitchOffset());
lookupSwitches.add(new LookupDetails(stringRef, bs));
}
}
break;
default:
break;
}
} finally {
stack.sawOpcode(this, seen);
if ((hashCodedStringRef != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(hashCodedStringRef);
}
if (!lookupSwitches.isEmpty()) {
int innerMostSwitch = lookupSwitches.size() - 1;
LookupDetails details = lookupSwitches.get(innerMostSwitch);
if (details.switchTargets.get(getPC()) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(details.getStringReference());
}
// runs on 1.7
if (getPC() >= details.getSwitchTargets().previousSetBit(Integer.MAX_VALUE)) {
lookupSwitches.remove(innerMostSwitch);
}
}
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class ConstantListIndex method isArrayFromUbiquitousMethod.
/**
* returns whether the array item was returned from a common method that the user can't do anything about and so don't report CLI in this case.
*
* @param item
* the stack item representing the array
* @return if the array was returned from a common method
*/
private static boolean isArrayFromUbiquitousMethod(OpcodeStack.Item item) {
XMethod method = item.getReturnValueOf();
if (method == null) {
return false;
}
FQMethod methodDesc = new FQMethod(method.getClassName().replace('.', '/'), method.getName(), method.getSignature());
return ubiquitousMethods.contains(methodDesc);
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class LoggerOddities method sawOpcode.
/**
* implements the visitor to look for calls to Logger.getLogger with the wrong class name
*
* @param seen
* the opcode of the currently parsed instruction
*/
@Override
@SuppressWarnings("unchecked")
public void sawOpcode(int seen) {
String ldcClassName = null;
String seenMethodName = null;
boolean seenToString = false;
boolean seenFormatterLogger = false;
int exMessageReg = -1;
Integer arraySize = null;
boolean simpleFormat = false;
try {
stack.precomputation(this);
if ((seen == Const.LDC) || (seen == Const.LDC_W)) {
Constant c = getConstantRefOperand();
if (c instanceof ConstantClass) {
ConstantPool pool = getConstantPool();
ldcClassName = ((ConstantUtf8) pool.getConstant(((ConstantClass) c).getNameIndex())).getBytes();
}
} else if (seen == Const.INVOKESTATIC) {
lookForSuspectClasses();
String clsName = getClassConstantOperand();
String methodName = getNameConstantOperand();
if (Values.SLASHED_JAVA_LANG_STRING.equals(clsName) && "format".equals(methodName) && (stack.getStackDepth() >= 2)) {
String format = (String) stack.getStackItem(1).getConstant();
if (format != null) {
Matcher m = NON_SIMPLE_FORMAT.matcher(format);
if (!m.matches()) {
simpleFormat = true;
}
}
} else if ("getFormatterLogger".equals(methodName) && LOG4J2_LOGMANAGER.equals(clsName)) {
seenFormatterLogger = true;
}
} else if (((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) && (throwableClass != null)) {
String mthName = getNameConstantOperand();
if ("getName".equals(mthName)) {
if (stack.getStackDepth() >= 1) {
// Foo.class.getName() is being called, so we pass the
// name of the class to the current top of the stack
// (the name of the class is currently on the top of the
// stack, but won't be on the stack at all next opcode)
Item stackItem = stack.getStackItem(0);
LOUserValue<String> uv = (LOUserValue<String>) stackItem.getUserValue();
if ((uv != null) && (uv.getType() == LOUserValue.LOType.CLASS_NAME)) {
ldcClassName = uv.getValue();
}
}
} else if ("getMessage".equals(mthName)) {
String callingClsName = getClassConstantOperand();
JavaClass cls = Repository.lookupClass(callingClsName);
if (cls.instanceOf(throwableClass) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item exItem = stack.getStackItem(0);
exMessageReg = exItem.getRegisterNumber();
}
} else if (LOGGER_METHODS.contains(mthName)) {
checkForProblemsWithLoggerMethods();
} else if (Values.TOSTRING.equals(mthName) && SignatureBuilder.SIG_VOID_TO_STRING.equals(getSigConstantOperand())) {
String callingClsName = getClassConstantOperand();
if (SignatureUtils.isPlainStringConvertableClass(callingClsName) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
// if the stringbuilder was previously stored, don't report it
if (item.getRegisterNumber() < 0) {
seenMethodName = mthName;
}
}
if (seenMethodName == null) {
seenToString = true;
}
}
} else if (seen == Const.INVOKESPECIAL) {
checkForLoggerParam();
} else if (seen == Const.ANEWARRAY) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item sizeItem = stack.getStackItem(0);
Object con = sizeItem.getConstant();
if (con instanceof Integer) {
arraySize = (Integer) con;
}
}
} else if (seen == Const.AASTORE) {
if (stack.getStackDepth() >= 3) {
OpcodeStack.Item arrayItem = stack.getStackItem(2);
LOUserValue<Integer> uv = (LOUserValue<Integer>) arrayItem.getUserValue();
if ((uv != null) && (uv.getType() == LOUserValue.LOType.ARRAY_SIZE)) {
Integer size = uv.getValue();
if ((size != null) && (size.intValue() > 0) && hasExceptionOnStack()) {
arrayItem.setUserValue(new LOUserValue<>(LOUserValue.LOType.ARRAY_SIZE, Integer.valueOf(-size.intValue())));
}
}
}
} else if (seen == PUTSTATIC) {
OpcodeStack.Item itm = stack.getStackItem(0);
if (isStaticInitializer && isNonPrivateLogField(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand())) {
XMethod m = itm.getReturnValueOf();
if ((m != null) && isLoggerWithClassParm(m)) {
bugReporter.reportBug(new BugInstance(this, BugType.LO_NON_PRIVATE_STATIC_LOGGER.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
LOUserValue<Void> loggerUV = (LOUserValue<Void>) itm.getUserValue();
if ((loggerUV != null) && (loggerUV.getType() == LOUserValue.LOType.FORMATTER_LOGGER)) {
formatterLoggers.add(getNameConstantOperand());
}
} else if (seen == GETSTATIC) {
if (formatterLoggers.contains(getNameConstantOperand())) {
seenFormatterLogger = true;
}
} else if (OpcodeUtils.isAStore(seen) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
LOUserValue<String> uv = (LOUserValue<String>) item.getUserValue();
if (uv != null) {
if (((uv.getType() == LOUserValue.LOType.METHOD_NAME) && Values.TOSTRING.equals(uv.getValue())) || (uv.getType() == LOUserValue.LOType.SIMPLE_FORMAT) || (uv.getType() == LOUserValue.LOType.TOSTRING)) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.NULL, null));
}
}
}
} catch (ClassNotFoundException cnfe) {
bugReporter.reportMissingClass(cnfe);
} finally {
TernaryPatcher.pre(stack, seen);
stack.sawOpcode(this, seen);
TernaryPatcher.post(stack, seen);
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
if (ldcClassName != null) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.CLASS_NAME, ldcClassName));
} else if (seenMethodName != null) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.METHOD_NAME, seenMethodName));
} else if (exMessageReg >= 0) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.MESSAGE_REG, Integer.valueOf(exMessageReg)));
} else if (arraySize != null) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.ARRAY_SIZE, arraySize));
} else if (simpleFormat) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.SIMPLE_FORMAT, Boolean.TRUE));
} else if (seenToString) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.TOSTRING, null));
} else if (seenFormatterLogger) {
item.setUserValue(new LOUserValue<>(LOUserValue.LOType.FORMATTER_LOGGER, null));
}
}
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class InappropriateToStringUse method processInvokeVirtual.
@Nullable
private String processInvokeVirtual() throws ClassNotFoundException {
String methodName = getNameConstantOperand();
if (Values.TOSTRING.equals(methodName)) {
String signature = getSigConstantOperand();
if (SignatureBuilder.SIG_VOID_TO_STRING.equals(signature)) {
String className = getClassConstantOperand();
if (!validToStringClasses.contains(className) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
JavaClass cls = item.getJavaClass();
if (cls != null) {
return cls.getPackageName();
}
}
}
} else if (stringAlgoMethods.contains(methodName)) {
String className = getClassConstantOperand();
if (Values.SLASHED_JAVA_LANG_STRING.equals(className)) {
String signature = getSigConstantOperand();
int numParms = SignatureUtils.getNumParameters(signature);
if (stack.getStackDepth() > numParms) {
OpcodeStack.Item item = stack.getStackItem(numParms);
if (item.getUserValue() != null) {
XMethod xm = item.getReturnValueOf();
String tsPackage = null;
if (xm != null) {
tsPackage = xm.getPackageName();
}
if ((tsPackage == null) || !SignatureUtils.similarPackages(tsPackage, packageName, 2)) {
bugReporter.reportBug(new BugInstance(this, BugType.ITU_INAPPROPRIATE_TOSTRING_USE.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
}
}
}
return null;
}
Aggregations