use of edu.umd.cs.findbugs.OpcodeStack.Item in project fb-contrib by mebigfatguy.
the class LoggerOddities method checkForLoggerParam.
/**
* looks for slf4j calls where an exception is passed as a logger parameter, expecting to be substituted for a {} marker. As slf4j just passes the exception
* down to the message generation itself, the {} marker will go unpopulated.
*/
private void checkForLoggerParam() {
if (Values.CONSTRUCTOR.equals(getNameConstantOperand())) {
String cls = getClassConstantOperand();
if ((cls.startsWith("java/") || cls.startsWith("javax/")) && cls.endsWith("Exception")) {
String sig = getSigConstantOperand();
List<String> types = SignatureUtils.getParameterSignatures(sig);
if (types.size() <= stack.getStackDepth()) {
for (int i = 0; i < types.size(); i++) {
String parmSig = types.get(i);
if (Values.SIG_JAVA_LANG_STRING.equals(parmSig)) {
OpcodeStack.Item item = stack.getStackItem(types.size() - i - 1);
String cons = (String) item.getConstant();
if ((cons != null) && cons.contains("{}")) {
bugReporter.reportBug(new BugInstance(this, BugType.LO_EXCEPTION_WITH_LOGGER_PARMS.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
break;
}
}
}
}
}
}
}
use of edu.umd.cs.findbugs.OpcodeStack.Item 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.OpcodeStack.Item in project fb-contrib by mebigfatguy.
the class LoggerOddities method getVarArgsParmCount.
/**
* returns the number of parameters slf4j or log4j2 is expecting to inject into the format string
*
* @param signature
* the method signature of the error, warn, info, debug statement
* @return the number of expected parameters
*/
@SuppressWarnings("unchecked")
private int getVarArgsParmCount(String signature) {
if (SignatureBuilder.SIG_STRING_AND_OBJECT_TO_VOID.equals(signature)) {
return 1;
}
if (SIG_STRING_AND_TWO_OBJECTS_TO_VOID.equals(signature)) {
return 2;
}
OpcodeStack.Item item = stack.getStackItem(0);
LOUserValue<Integer> uv = (LOUserValue<Integer>) item.getUserValue();
if ((uv != null) && (uv.getType() == LOUserValue.LOType.ARRAY_SIZE)) {
Integer size = uv.getValue();
if (size != null) {
return Math.abs(size.intValue());
}
}
return -1;
}
Aggregations