Search in sources :

Example 16 with ConstantPool

use of org.apache.bcel.classfile.ConstantPool in project fb-contrib by mebigfatguy.

the class ExceptionSoftening method sawOpcode.

/**
 * overrides the visitor to find catch blocks that throw runtime exceptions
 *
 * @param seen
 *            the opcode of the currently parsed instruction
 */
@Override
public void sawOpcode(int seen) {
    try {
        stack.precomputation(this);
        int pc = getPC();
        CodeException ex = catchHandlerPCs.get(Integer.valueOf(pc));
        if (ex != null) {
            int endPC;
            if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                endPC = this.getBranchTarget();
            } else {
                endPC = Integer.MAX_VALUE;
            }
            ConstantPool pool = getConstantPool();
            ConstantClass ccls = (ConstantClass) pool.getConstant(ex.getCatchType());
            String catchSig = ccls.getBytes(pool);
            CatchInfo ci = new CatchInfo(ex.getHandlerPC(), endPC, catchSig);
            catchInfos.add(ci);
        }
        updateEndPCsOnCatchRegScope(catchInfos, pc, seen);
        removeFinishedCatchBlocks(catchInfos, pc);
        if (seen == Const.ATHROW) {
            processThrow();
        } else if ((seen == Const.IRETURN) && isBooleanMethod && !hasValidFalseReturn && (stack.getStackDepth() > 0)) {
            processBooleanReturn();
        }
    } finally {
        stack.sawOpcode(this, seen);
    }
}
Also used : CodeException(org.apache.bcel.classfile.CodeException) ConstantPool(org.apache.bcel.classfile.ConstantPool) ToString(com.mebigfatguy.fbcontrib.utils.ToString) ConstantClass(org.apache.bcel.classfile.ConstantClass)

Example 17 with ConstantPool

use of org.apache.bcel.classfile.ConstantPool 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));
            }
        }
    }
}
Also used : Item(edu.umd.cs.findbugs.OpcodeStack.Item) OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) Matcher(java.util.regex.Matcher) Constant(org.apache.bcel.classfile.Constant) BugInstance(edu.umd.cs.findbugs.BugInstance) ToString(com.mebigfatguy.fbcontrib.utils.ToString) Item(edu.umd.cs.findbugs.OpcodeStack.Item) JavaClass(org.apache.bcel.classfile.JavaClass) ConstantPool(org.apache.bcel.classfile.ConstantPool) XMethod(edu.umd.cs.findbugs.ba.XMethod) ConstantClass(org.apache.bcel.classfile.ConstantClass)

Aggregations

ConstantPool (org.apache.bcel.classfile.ConstantPool)17 ToString (com.mebigfatguy.fbcontrib.utils.ToString)7 BugInstance (edu.umd.cs.findbugs.BugInstance)7 Constant (org.apache.bcel.classfile.Constant)7 ConstantClass (org.apache.bcel.classfile.ConstantClass)6 ConstantNameAndType (org.apache.bcel.classfile.ConstantNameAndType)6 JavaClass (org.apache.bcel.classfile.JavaClass)5 ConstantMethodref (org.apache.bcel.classfile.ConstantMethodref)4 ConstantString (org.apache.bcel.classfile.ConstantString)4 ConstantUtf8 (org.apache.bcel.classfile.ConstantUtf8)4 OpcodeStack (edu.umd.cs.findbugs.OpcodeStack)3 ArrayList (java.util.ArrayList)3 ExceptionTable (org.apache.bcel.classfile.ExceptionTable)3 Method (org.apache.bcel.classfile.Method)3 BitSet (java.util.BitSet)2 HashSet (java.util.HashSet)2 Set (java.util.Set)2 Attribute (org.apache.bcel.classfile.Attribute)2 Code (org.apache.bcel.classfile.Code)2 ConstantInvokeDynamic (org.apache.bcel.classfile.ConstantInvokeDynamic)2