Search in sources :

Example 6 with StopOpcodeParsingException

use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.

the class MethodInfo method visitCode.

/**
 * implements the visitor to check to see what Const were returned from a comparator. If no Const were returned it can't determine anything, however if only
 * Const were returned, it looks to see if negative positive and zero was returned. It also looks to see if a non zero value is returned unconditionally.
 * While it is possible that later check is ok, it usually means something is wrong.
 *
 * @param obj
 *            the currently parsed code block
 */
@Override
public void visitCode(Code obj) {
    if (getMethod().isSynthetic()) {
        return;
    }
    String methodName = getMethodName();
    String methodSig = getMethodSig();
    if (methodName.equals(methodInfo.methodName) && methodSig.endsWith(methodInfo.signatureEnding) && (SignatureUtils.getNumParameters(methodSig) == methodInfo.argumentCount)) {
        stack.resetForMethodEntry(this);
        seenNegative = false;
        seenPositive = false;
        seenZero = false;
        seenUnconditionalNonZero = false;
        furthestBranchTarget = -1;
        sawConstant = null;
        try {
            super.visitCode(obj);
            if (!seenZero || seenUnconditionalNonZero || (obj.getCode().length > 2)) {
                boolean seenAll = seenNegative & seenPositive & seenZero;
                if (!seenAll || seenUnconditionalNonZero) {
                    bugReporter.reportBug(new BugInstance(this, BugType.SCRV_SUSPICIOUS_COMPARATOR_RETURN_VALUES.name(), seenAll ? LOW_PRIORITY : NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this, 0));
                }
            }
        } catch (StopOpcodeParsingException e) {
        // indeterminate
        }
    }
}
Also used : StopOpcodeParsingException(com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException) BugInstance(edu.umd.cs.findbugs.BugInstance) ToString(com.mebigfatguy.fbcontrib.utils.ToString)

Example 7 with StopOpcodeParsingException

use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.

the class OverlyConcreteParameter method sawOpcode.

/**
 * implements the visitor to filter out parameter use where the actual defined type of the method declaration is needed. What remains could be more
 * abstractly defined.
 *
 * @param seen
 *            the currently parsed opcode
 */
@Override
public void sawOpcode(final int seen) {
    try {
        stack.precomputation(this);
        if (OpcodeUtils.isInvoke(seen)) {
            String methodSig = getSigConstantOperand();
            List<String> parmTypes = SignatureUtils.getParameterSignatures(methodSig);
            int stackDepth = stack.getStackDepth();
            if (stackDepth >= parmTypes.size()) {
                for (int i = 0; i < parmTypes.size(); i++) {
                    OpcodeStack.Item itm = stack.getStackItem(i);
                    int reg = itm.getRegisterNumber();
                    removeUselessDefiners(parmTypes.get(parmTypes.size() - i - 1), reg);
                }
            }
            if ((seen != Const.INVOKESPECIAL) && (seen != Const.INVOKESTATIC)) {
                if (stackDepth > parmTypes.size()) {
                    OpcodeStack.Item itm = stack.getStackItem(parmTypes.size());
                    int reg = itm.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }
                    if ((parm >= 0) && (parm < parmCount)) {
                        removeUselessDefiners(reg);
                    }
                } else {
                    parameterDefiners.clear();
                }
            }
        } else if ((seen == Const.PUTFIELD) || (seen == Const.GETFIELD) || (seen == Const.PUTSTATIC) || (seen == Const.GETSTATIC) || OpcodeUtils.isAStore(seen)) {
            // Don't check parameters that are aliased
            if (stack.getStackDepth() > 0) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                int reg = itm.getRegisterNumber();
                int parm = reg;
                if (!methodIsStatic) {
                    parm--;
                }
                if ((parm >= 0) && (parm < parmCount)) {
                    parameterDefiners.remove(Integer.valueOf(reg));
                }
            } else {
                parameterDefiners.clear();
            }
            if ((seen == Const.GETFIELD) || (seen == Const.PUTFIELD)) {
                if (stack.getStackDepth() > 1) {
                    OpcodeStack.Item itm = stack.getStackItem(1);
                    int reg = itm.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }
                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }
            }
        } else if (OpcodeUtils.isALoad(seen)) {
            int reg = RegisterUtils.getALoadReg(this, seen);
            int parm = reg;
            if (!methodIsStatic) {
                parm--;
            }
            if ((parm >= 0) && (parm < parmCount)) {
                usedParameters.set(reg);
            }
        } else if (seen == Const.AASTORE) {
            // Don't check parameters that are stored in
            if (stack.getStackDepth() >= 3) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                int reg = itm.getRegisterNumber();
                int parm = reg;
                if (!methodIsStatic) {
                    parm--;
                }
                if ((parm >= 0) && (parm < parmCount)) {
                    parameterDefiners.remove(Integer.valueOf(reg));
                }
            } else {
                parameterDefiners.clear();
            }
        } else if (seen == Const.ARETURN) {
            if (stack.getStackDepth() >= 1) {
                OpcodeStack.Item item = stack.getStackItem(0);
                int reg = item.getRegisterNumber();
                int parm = reg;
                if (!methodIsStatic) {
                    parm--;
                }
                if ((parm >= 0) && (parm < parmCount)) {
                    parameterDefiners.remove(Integer.valueOf(reg));
                }
            } else {
                parameterDefiners.clear();
            }
        }
        if (parameterDefiners.isEmpty()) {
            throw new StopOpcodeParsingException();
        }
    } finally {
        stack.sawOpcode(this, seen);
    }
}
Also used : OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) StopOpcodeParsingException(com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException) ToString(com.mebigfatguy.fbcontrib.utils.ToString)

Example 8 with StopOpcodeParsingException

use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.

the class PartiallyConstructedObjectAccess method visitCode.

@Override
public void visitCode(final Code obj) {
    stack.resetForMethodEntry(this);
    String methodName = getMethodName();
    isCtor = Values.CONSTRUCTOR.equals(methodName);
    if (!Values.STATIC_INITIALIZER.equals(methodName)) {
        Method m = getMethod();
        methodToCalledMethods.put(m, new HashMap<Method, SourceLineAnnotation>());
        try {
            super.visitCode(obj);
            if (methodToCalledMethods.get(m).isEmpty()) {
                methodToCalledMethods.remove(getMethod());
            }
        } catch (StopOpcodeParsingException e) {
            methodToCalledMethods.remove(getMethod());
        }
    }
}
Also used : SourceLineAnnotation(edu.umd.cs.findbugs.SourceLineAnnotation) StopOpcodeParsingException(com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException) Method(org.apache.bcel.classfile.Method)

Example 9 with StopOpcodeParsingException

use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.

the class PoorMansEnum method visitClassContext.

@Override
public void visitClassContext(ClassContext classContext) {
    try {
        JavaClass cls = classContext.getJavaClass();
        if (cls.getMajor() >= Const.MAJOR_1_5) {
            fieldValues = new HashMap<>();
            nameToField = new HashMap<>();
            for (Field f : cls.getFields()) {
                if (f.isPrivate() && !f.isSynthetic()) {
                    String fieldName = f.getName();
                    // preallocating a set per field is just a waste, so just insert the empty set as a place holder
                    fieldValues.put(fieldName, Collections.emptySet());
                    nameToField.put(fieldName, f);
                }
            }
            if (!fieldValues.isEmpty()) {
                stack = new OpcodeStack();
                firstFieldUse = new HashMap<>();
                try {
                    super.visitClassContext(classContext);
                    for (Map.Entry<String, Set<Object>> fieldInfo : fieldValues.entrySet()) {
                        Set<Object> values = fieldInfo.getValue();
                        if (values.size() >= 3) {
                            String fieldName = fieldInfo.getKey();
                            bugReporter.reportBug(new BugInstance(this, BugType.PME_POOR_MANS_ENUM.name(), NORMAL_PRIORITY).addClass(this).addField(XFactory.createXField(cls, nameToField.get(fieldName))).addSourceLine(firstFieldUse.get(fieldName)));
                        }
                    }
                } catch (StopOpcodeParsingException e) {
                // no fields left
                }
            }
        }
    } finally {
        fieldValues = null;
        nameToField = null;
        firstFieldUse = null;
        stack = null;
    }
}
Also used : Field(org.apache.bcel.classfile.Field) Set(java.util.Set) HashSet(java.util.HashSet) JavaClass(org.apache.bcel.classfile.JavaClass) OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) StopOpcodeParsingException(com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException) BugInstance(edu.umd.cs.findbugs.BugInstance) HashMap(java.util.HashMap) Map(java.util.Map)

Example 10 with StopOpcodeParsingException

use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.

the class MethodReturnsConstant method sawOpcode.

/**
 * implements the visitor to look for methods that return a constant
 *
 * @param seen
 *            the opcode of the currently parsed instruction
 */
@Override
public void sawOpcode(int seen) {
    boolean sawSBToString = false;
    try {
        stack.precomputation(this);
        if ((seen >= Const.IRETURN) && (seen <= Const.ARETURN)) {
            if (stack.getStackDepth() > 0) {
                OpcodeStack.Item item = stack.getStackItem(0);
                Integer register = Integer.valueOf(item.getRegisterNumber());
                Object constant = registerConstants.get(register);
                if (CONSTANT_DOESNT_EXIST.equals(constant)) {
                    throw new StopOpcodeParsingException();
                }
                String returnSig = item.getSignature();
                if ((returnSig != null) && returnSig.startsWith(Values.SIG_ARRAY_PREFIX)) {
                    XField f = item.getXField();
                    if ((f == null) || (!f.isStatic())) {
                        throw new StopOpcodeParsingException();
                    }
                }
                constant = item.getConstant();
                if (constant == null) {
                    throw new StopOpcodeParsingException();
                }
                if (Boolean.TRUE.equals(item.getUserValue()) && ("".equals(constant))) {
                    throw new StopOpcodeParsingException();
                }
                if ((returnConstant != null) && (!returnConstant.equals(constant))) {
                    throw new StopOpcodeParsingException();
                }
                returnRegister = Integer.valueOf(item.getRegisterNumber());
                returnConstant = constant;
                returnPC = getPC();
            }
        } else if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
            if (stack.getStackDepth() > 0) {
                // Ternaries confuse us too much, if the code has a ternary well - oh well
                throw new StopOpcodeParsingException();
            }
        } else if (seen == Const.ATHROW) {
            throw new StopOpcodeParsingException();
        } else if (seen == Const.INVOKEVIRTUAL) {
            String clsName = getClassConstantOperand();
            if (SignatureUtils.isPlainStringConvertableClass(clsName)) {
                sawSBToString = Values.TOSTRING.equals(getNameConstantOperand());
            }
        } else if (((seen >= Const.ISTORE) && (seen <= Const.ASTORE_3)) || (seen == Const.IINC)) {
            Integer register = Integer.valueOf(getRegisterOperand());
            if ((returnRegister.intValue() != -1) && (register.equals(returnRegister))) {
                throw new StopOpcodeParsingException();
            }
            if (stack.getStackDepth() > 0) {
                OpcodeStack.Item item = stack.getStackItem(0);
                Object constant = item.getConstant();
                Object regConstant = registerConstants.get(register);
                if (regConstant != null) {
                    if ((constant == null) || !constant.equals(regConstant)) {
                        registerConstants.put(register, CONSTANT_DOESNT_EXIST);
                    }
                } else {
                    if (item.getSignature().contains(Values.SIG_ARRAY_PREFIX)) {
                        registerConstants.put(register, CONSTANT_DOESNT_EXIST);
                    } else {
                        registerConstants.put(register, constant == null ? CONSTANT_DOESNT_EXIST : constant);
                    }
                }
            } else {
                registerConstants.put(register, CONSTANT_DOESNT_EXIST);
            }
            if (returnRegister.equals(register)) {
                Object constant = registerConstants.get(returnRegister);
                if (CONSTANT_DOESNT_EXIST.equals(constant)) {
                    throw new StopOpcodeParsingException();
                }
            }
        }
    } finally {
        TernaryPatcher.pre(stack, seen);
        stack.sawOpcode(this, seen);
        TernaryPatcher.post(stack, seen);
        if (sawSBToString && (stack.getStackDepth() > 0)) {
            OpcodeStack.Item item = stack.getStackItem(0);
            item.setUserValue(Boolean.TRUE);
        }
    }
}
Also used : OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) XField(edu.umd.cs.findbugs.ba.XField) StopOpcodeParsingException(com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException)

Aggregations

StopOpcodeParsingException (com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException)24 BugInstance (edu.umd.cs.findbugs.BugInstance)11 Method (org.apache.bcel.classfile.Method)11 OpcodeStack (edu.umd.cs.findbugs.OpcodeStack)8 JavaClass (org.apache.bcel.classfile.JavaClass)5 XField (edu.umd.cs.findbugs.ba.XField)4 ToString (com.mebigfatguy.fbcontrib.utils.ToString)3 SourceLineAnnotation (edu.umd.cs.findbugs.SourceLineAnnotation)2 CodeException (org.apache.bcel.classfile.CodeException)2 ImmutabilityType (com.mebigfatguy.fbcontrib.collect.ImmutabilityType)1 MethodInfo (com.mebigfatguy.fbcontrib.collect.MethodInfo)1 BugType (com.mebigfatguy.fbcontrib.utils.BugType)1 QMethod (com.mebigfatguy.fbcontrib.utils.QMethod)1 BitSet (java.util.BitSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Set (java.util.Set)1 Code (org.apache.bcel.classfile.Code)1 ExceptionTable (org.apache.bcel.classfile.ExceptionTable)1