Search in sources :

Example 6 with QMethod

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

the class SpoiledChildInterfaceImplementor method buildMethodSet.

/**
 * builds a set of all non constructor or static initializer method/signatures
 *
 * @param cls
 *            the class to build the method set from
 * @return a set of method names/signatures
 */
private static Set<QMethod> buildMethodSet(JavaClass cls) {
    Set<QMethod> methods = new HashSet<>();
    boolean isInterface = cls.isInterface();
    for (Method m : cls.getMethods()) {
        boolean isDefaultInterfaceMethod = isInterface && !m.isAbstract();
        boolean isSyntheticForParentCall;
        if (m.isSynthetic()) {
            BitSet bytecodeSet = ClassContext.getBytecodeSet(cls, m);
            isSyntheticForParentCall = (bytecodeSet != null) && bytecodeSet.get(Const.INVOKESPECIAL);
        } else {
            isSyntheticForParentCall = false;
        }
        if (!isSyntheticForParentCall && !isDefaultInterfaceMethod) {
            String methodName = m.getName();
            QMethod methodInfo = new QMethod(methodName, m.getSignature());
            if (!OBJECT_METHODS.contains(methodInfo)) {
                if (!Values.CONSTRUCTOR.equals(methodName) && !Values.STATIC_INITIALIZER.equals(methodName)) {
                    methods.add(methodInfo);
                }
            }
        }
    }
    return methods;
}
Also used : QMethod(com.mebigfatguy.fbcontrib.utils.QMethod) BitSet(java.util.BitSet) Method(org.apache.bcel.classfile.Method) QMethod(com.mebigfatguy.fbcontrib.utils.QMethod) ToString(com.mebigfatguy.fbcontrib.utils.ToString) HashSet(java.util.HashSet)

Example 7 with QMethod

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

the class NonRecycleableTaglibs method sawOpcode.

/**
 * implements the visitor to record storing of fields, and where they occur
 *
 * @param seen
 *            the currently parsed opcode
 */
@Override
public void sawOpcode(int seen) {
    if (seen == PUTFIELD) {
        QMethod methodInfo = new QMethod(getMethodName(), getMethodSig());
        Map<Map.Entry<String, String>, SourceLineAnnotation> fields = methodWrites.get(methodInfo);
        if (fields == null) {
            fields = new HashMap<>();
            methodWrites.put(methodInfo, fields);
        }
        String fieldName = getNameConstantOperand();
        String fieldSig = getSigConstantOperand();
        FieldAnnotation fa = new FieldAnnotation(getDottedClassName(), fieldName, fieldSig, false);
        fieldAnnotations.put(fieldName, fa);
        fields.put(new AbstractMap.SimpleImmutableEntry(fieldName, fieldSig), SourceLineAnnotation.fromVisitedInstruction(this));
    }
}
Also used : AbstractMap(java.util.AbstractMap) QMethod(com.mebigfatguy.fbcontrib.utils.QMethod) SourceLineAnnotation(edu.umd.cs.findbugs.SourceLineAnnotation) FieldAnnotation(edu.umd.cs.findbugs.FieldAnnotation)

Example 8 with QMethod

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

the class NonRecycleableTaglibs method reportBugs.

/**
 * generates all the bug reports for attributes that are not recycleable
 */
private void reportBugs() {
    for (Map.Entry<QMethod, String> attEntry : attributes.entrySet()) {
        QMethod methodInfo = attEntry.getKey();
        String attType = attEntry.getValue();
        Map<Map.Entry<String, String>, SourceLineAnnotation> fields = methodWrites.get(methodInfo);
        if ((fields == null) || (fields.size() != 1)) {
            continue;
        }
        Map.Entry<String, String> fieldInfo = fields.keySet().iterator().next();
        String fieldType = fieldInfo.getValue();
        if (!attType.equals(fieldType)) {
            continue;
        }
        String fieldName = fieldInfo.getKey();
        for (Map.Entry<QMethod, Map<Map.Entry<String, String>, SourceLineAnnotation>> fwEntry : methodWrites.entrySet()) {
            if (fwEntry.getKey().equals(methodInfo)) {
                continue;
            }
            SourceLineAnnotation sla = fwEntry.getValue().get(fieldInfo);
            if (sla != null) {
                bugReporter.reportBug(new BugInstance(this, BugType.NRTL_NON_RECYCLEABLE_TAG_LIB.name(), NORMAL_PRIORITY).addClass(this).addField(fieldAnnotations.get(fieldName)).addSourceLine(sla));
                break;
            }
        }
    }
}
Also used : QMethod(com.mebigfatguy.fbcontrib.utils.QMethod) SourceLineAnnotation(edu.umd.cs.findbugs.SourceLineAnnotation) BugInstance(edu.umd.cs.findbugs.BugInstance) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap) Map(java.util.Map)

Example 9 with QMethod

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

the class MapUsageIssues method sawOpcode.

@Override
public void sawOpcode(int seen) {
    try {
        if (!mapContainsKeyUsed.isEmpty()) {
            Iterator<Map.Entry<MapRef, ContainsKey>> it = mapContainsKeyUsed.entrySet().iterator();
            int pc = getPC();
            while (it.hasNext()) {
                Map.Entry<MapRef, ContainsKey> entry = it.next();
                if (!entry.getKey().isValid() || entry.getValue().outOfScope(pc)) {
                    it.remove();
                }
            }
        }
        // checking for a branch might be overkill, but for now lets go with it
        if (!mapGetUsed.isEmpty() && OpcodeUtils.isBranch(seen)) {
            Iterator<Map.Entry<MapRef, Get>> it = mapGetUsed.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<MapRef, Get> entry = it.next();
                it.remove();
            }
        }
        if ((seen == Const.IFNULL) || (seen == Const.IFNONNULL)) {
            if (stack.getStackDepth() > 0) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                XMethod method = itm.getReturnValueOf();
                if ((method != null) && (mapClass != null)) {
                    if (COLLECTION_ACCESSORS.contains(method.getName())) {
                        JavaClass cls = Repository.lookupClass(method.getClassName());
                        if (cls.implementationOf(mapClass)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.MUI_NULL_CHECK_ON_MAP_SUBSET_ACCESSOR.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                        }
                    }
                }
            }
        } else if (seen == Const.INVOKEINTERFACE) {
            FQMethod fqm = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand());
            if (CONTAINS_METHOD.equals(fqm)) {
                if (stack.getStackDepth() >= 2) {
                    OpcodeStack.Item item = stack.getStackItem(1);
                    if ((item.getRegisterNumber() < 0) && (item.getXField() == null)) {
                        XMethod xm = item.getReturnValueOf();
                        if ((xm != null) && COLLECTION_ACCESSORS.contains(xm.getName()) && Values.DOTTED_JAVA_UTIL_MAP.equals(xm.getClassName())) {
                            bugReporter.reportBug(new BugInstance(this, BugType.MUI_USE_CONTAINSKEY.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                        }
                    }
                }
            } else if (CONTAINSKEY_METHOD.equals(fqm)) {
                if (getNextOpcode() == Const.IFEQ) {
                    int ifEnd = getNextPC() + CodeByteUtils.getshort(getCode().getCode(), getNextPC() + 1);
                    if (stack.getStackDepth() >= 2) {
                        OpcodeStack.Item itm = stack.getStackItem(1);
                        mapContainsKeyUsed.put(new MapRef(itm), new ContainsKey(stack.getStackItem(0), ifEnd));
                    }
                }
            } else if (GET_METHOD.equals(fqm)) {
                if (stack.getStackDepth() >= 2) {
                    OpcodeStack.Item itm = stack.getStackItem(1);
                    ContainsKey ck = mapContainsKeyUsed.remove(new MapRef(itm));
                    if ((ck != null) && new ContainsKey(stack.getStackItem(0), 0).equals(ck)) {
                        bugReporter.reportBug(new BugInstance(this, BugType.MUI_CONTAINSKEY_BEFORE_GET.name(), ck.getReportLevel()).addClass(this).addMethod(this).addSourceLine(this));
                    }
                    mapGetUsed.put(new MapRef(itm), new Get(stack.getStackItem(0)));
                }
            } else if (REMOVE_METHOD.equals(fqm)) {
                if (stack.getStackDepth() >= 2) {
                    OpcodeStack.Item itm = stack.getStackItem(1);
                    Get get = mapGetUsed.remove(new MapRef(itm));
                    if ((get != null) && new Get(stack.getStackItem(0)).equals(get)) {
                        bugReporter.reportBug(new BugInstance(this, BugType.MUI_GET_BEFORE_REMOVE.name(), get.getReportLevel()).addClass(this).addMethod(this).addSourceLine(this));
                    }
                }
            }
            QMethod qm = new QMethod(getNameConstantOperand(), getSigConstantOperand());
            if (SIZE_METHOD.equals(qm)) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    if ((itm.getRegisterNumber() < 0) && (itm.getXField() == null)) {
                        XMethod xm = itm.getReturnValueOf();
                        if ((xm != null) && Values.DOTTED_JAVA_UTIL_MAP.equals(xm.getClassName()) && COLLECTION_ACCESSORS.contains(xm.getName())) {
                            bugReporter.reportBug(new BugInstance(this, BugType.MUI_CALLING_SIZE_ON_SUBCONTAINER.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                        }
                    }
                }
            }
        }
    } catch (ClassNotFoundException e) {
        bugReporter.reportMissingClass(e);
    } finally {
        stack.sawOpcode(this, seen);
    }
}
Also used : OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) BugInstance(edu.umd.cs.findbugs.BugInstance) QMethod(com.mebigfatguy.fbcontrib.utils.QMethod) FQMethod(com.mebigfatguy.fbcontrib.utils.FQMethod) JavaClass(org.apache.bcel.classfile.JavaClass) XMethod(edu.umd.cs.findbugs.ba.XMethod) FQMethod(com.mebigfatguy.fbcontrib.utils.FQMethod) HashMap(java.util.HashMap) Map(java.util.Map)

Example 10 with QMethod

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

the class SillynessPotPourri method stringSilliness.

private SPPUserValue stringSilliness(String methodName, String signature) {
    Integer stackOffset = methodsThatAreSillyOnStringLiterals.get(new QMethod(methodName, signature));
    int offset;
    if ((stackOffset != null) && (stack.getStackDepth() > (offset = stackOffset.intValue()))) {
        OpcodeStack.Item itm = stack.getStackItem(offset);
        Object constant = itm.getConstant();
        if ((constant != null) && constant.getClass().equals(String.class) && (itm.getXField() == null)) {
            int priority = NORMAL_PRIORITY;
            if (SignatureUtils.getNumParameters(getSigConstantOperand()) > 0) {
                // if an argument is passed in, it may be
                // locale-specific
                priority = LOW_PRIORITY;
            }
            bugReporter.reportBug(new BugInstance(this, BugType.SPP_CONVERSION_OF_STRING_LITERAL.name(), priority).addClass(this).addMethod(this).addSourceLine(this).addCalledMethod(this));
        }
    }
    // not an elseif because the below cases might be in the set
    // methodsThatAreSillyOnStringLiterals
    SPPUserValue userValue = null;
    if ("intern".equals(methodName)) {
        String owningMethod = getMethod().getName();
        if (!Values.STATIC_INITIALIZER.equals(owningMethod) && (stack.getStackDepth() > 0)) {
            OpcodeStack.Item item = stack.getStackItem(0);
            if (item.getConstant() != null) {
                bugReporter.reportBug(new BugInstance(this, BugType.SPP_INTERN_ON_CONSTANT.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
            }
        }
    } else if ("toCharArray".equals(methodName)) {
        userValue = new SPPUserValue(SPPMethod.TOCHARARRAY);
    } else if ("toLowerCase".equals(methodName) || "toUpperCase".equals(methodName)) {
        userValue = new SPPUserValue(SPPMethod.IGNORECASE);
    } else if ("equalsIgnoreCase".equals(methodName) || "compareToIgnoreCase".equals(methodName)) {
        if (stack.getStackDepth() > 1) {
            OpcodeStack.Item item = stack.getStackItem(1);
            SPPUserValue uv = (SPPUserValue) item.getUserValue();
            if ((uv != null) && (uv.getMethod() == SPPMethod.IGNORECASE)) {
                bugReporter.reportBug(new BugInstance(this, BugType.SPP_USELESS_CASING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
            }
            item = stack.getStackItem(0);
            String parm = (String) item.getConstant();
            if ("".equals(parm)) {
                bugReporter.reportBug(new BugInstance(this, BugType.SPP_EMPTY_CASING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
            }
        }
    } else if ("trim".equals(methodName)) {
        userValue = getTrimUserValue();
    } else if ("length".equals(methodName)) {
        if (stack.getStackDepth() > 0) {
            checkForTrim(stack.getStackItem(0));
        }
    } else if ("equals".equals(methodName)) {
        if (stack.getStackDepth() > 1) {
            checkForTrim(stack.getStackItem(1));
        }
    } else if (Values.TOSTRING.equals(methodName)) {
        bugReporter.reportBug(new BugInstance(this, BugType.SPP_TOSTRING_ON_STRING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
    }
    return userValue;
}
Also used : QMethod(com.mebigfatguy.fbcontrib.utils.QMethod) OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) BugInstance(edu.umd.cs.findbugs.BugInstance) ToString(com.mebigfatguy.fbcontrib.utils.ToString) ConstantString(org.apache.bcel.classfile.ConstantString)

Aggregations

QMethod (com.mebigfatguy.fbcontrib.utils.QMethod)14 BugInstance (edu.umd.cs.findbugs.BugInstance)7 OpcodeStack (edu.umd.cs.findbugs.OpcodeStack)6 ToString (com.mebigfatguy.fbcontrib.utils.ToString)5 HashMap (java.util.HashMap)5 Map (java.util.Map)4 JavaClass (org.apache.bcel.classfile.JavaClass)4 FQMethod (com.mebigfatguy.fbcontrib.utils.FQMethod)2 FieldAnnotation (edu.umd.cs.findbugs.FieldAnnotation)2 SourceLineAnnotation (edu.umd.cs.findbugs.SourceLineAnnotation)2 XMethod (edu.umd.cs.findbugs.ba.XMethod)2 AbstractMap (java.util.AbstractMap)2 HashSet (java.util.HashSet)2 Method (org.apache.bcel.classfile.Method)2 ImmutabilityType (com.mebigfatguy.fbcontrib.collect.ImmutabilityType)1 MethodInfo (com.mebigfatguy.fbcontrib.collect.MethodInfo)1 StopOpcodeParsingException (com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException)1 UnmodifiableSet (com.mebigfatguy.fbcontrib.utils.UnmodifiableSet)1 XField (edu.umd.cs.findbugs.ba.XField)1 FieldDescriptor (edu.umd.cs.findbugs.classfile.FieldDescriptor)1