Class FindRefComparison

  • All Implemented Interfaces:
    ExtendedTypes, Detector, Priorities

    public class FindRefComparison
    extends java.lang.Object
    implements Detector, ExtendedTypes
    Find suspicious reference comparisons. This includes:
    • Strings and other java.lang objects compared by reference equality
    • Calls to equals(Object) where the argument is a different type than the receiver object
    • Field Detail

      • DEBUG

        private static final boolean DEBUG
      • BASE_ES_PRIORITY

        private static final int BASE_ES_PRIORITY
      • DEFAULT_SUSPICIOUS_SET

        @StaticConstant
        private static final java.util.Set<java.lang.String> DEFAULT_SUSPICIOUS_SET
        Classes that are suspicious if compared by reference.
      • invokeInstanceSet

        private static final java.util.BitSet invokeInstanceSet
        Set of opcodes that invoke instance methods on an object.
      • prescreenSet

        private static final java.util.BitSet prescreenSet
        Set of bytecodes using for prescreening.
      • STRING_SIGNATURE

        private static final java.lang.String STRING_SIGNATURE
        See Also:
        Constant Field Values
      • dynamicStringTypeInstance

        private static final org.apache.bcel.generic.Type dynamicStringTypeInstance
      • staticStringTypeInstance

        private static final org.apache.bcel.generic.Type staticStringTypeInstance
      • emptyStringTypeInstance

        private static final org.apache.bcel.generic.Type emptyStringTypeInstance
      • parameterStringTypeInstance

        private static final org.apache.bcel.generic.Type parameterStringTypeInstance
      • suspiciousSet

        private final java.util.Set<java.lang.String> suspiciousSet
      • testingEnabled

        private final boolean testingEnabled
      • comparedForEqualityInThisMethod

        private java.util.Map<java.lang.String,​java.lang.Integer> comparedForEqualityInThisMethod
    • Constructor Detail

      • FindRefComparison

        public FindRefComparison​(BugReporter bugReporter)
    • Method Detail

      • reportAllRefComparisons

        private boolean reportAllRefComparisons()
      • visitClassContext

        public void visitClassContext​(ClassContext classContext)
        Description copied from interface: Detector
        Visit the ClassContext for a class which should be analyzed for instances of bug patterns.
        Specified by:
        visitClassContext in interface Detector
        Parameters:
        classContext - the ClassContext
      • isLombokWithMethod

        private boolean isLombokWithMethod​(org.apache.bcel.classfile.Method method)
        Lombok's "with" methods include an == comparison reported as RC_REF_COMPARISON.
        Returns:
        true if the method is generated with Lombok's @With annotation
      • isComparisonInsideEqualsMethod

        private static boolean isComparisonInsideEqualsMethod​(org.apache.bcel.classfile.JavaClass jClass,
                                                              org.apache.bcel.classfile.Method method,
                                                              org.apache.bcel.generic.Type lhsType,
                                                              org.apache.bcel.generic.Type rhsType)
        Identifies if it's a comparison of two instances of the class inside its equals method or if it's a comparison of the class with Object. This should be OK as this is usually an optimization inside the equals method.
        Parameters:
        jClass - : the class where this check is running on
        method - : the method where the comparison is happening
        lhsType - : the type of the left hand side of the comparison
        rhsType - : the type of the right hand side of the comparison
        Returns:
        whether it's an acceptable comparison inside the equals method
      • comparingEnumsSameType

        private static boolean comparingEnumsSameType​(org.apache.bcel.generic.Type lhsType,
                                                      org.apache.bcel.generic.Type rhsType)
      • resolveJavaClass

        private static org.apache.bcel.classfile.JavaClass resolveJavaClass​(org.apache.bcel.generic.Type type)
      • comparingClasses

        private static boolean comparingClasses​(org.apache.bcel.generic.Type lhsType,
                                                org.apache.bcel.generic.Type rhsType)
      • isClassType

        private static boolean isClassType​(org.apache.bcel.generic.Type type)
      • handleSuspiciousRefComparison

        private void handleSuspiciousRefComparison​(org.apache.bcel.classfile.JavaClass jclass,
                                                   org.apache.bcel.classfile.Method method,
                                                   org.apache.bcel.generic.MethodGen methodGen,
                                                   java.util.List<FindRefComparison.WarningWithProperties> refComparisonList,
                                                   Location location,
                                                   java.lang.String lhs,
                                                   org.apache.bcel.generic.ReferenceType lhsType,
                                                   org.apache.bcel.generic.ReferenceType rhsType,
                                                   java.util.Optional<java.lang.Integer> priorityOverride)
      • addEqualsCheck

        void addEqualsCheck​(java.lang.String type,
                            int pc)
      • checkEqualsComparison

        private void checkEqualsComparison​(Location location,
                                           org.apache.bcel.classfile.JavaClass jclass,
                                           org.apache.bcel.classfile.Method method,
                                           org.apache.bcel.generic.MethodGen methodGen,
                                           org.apache.bcel.generic.ConstantPoolGen cpg,
                                           TypeDataflow typeDataflow)
                                    throws DataflowAnalysisException
        Throws:
        DataflowAnalysisException
      • getMethodCalledAnnotation

        @CheckForNull
        public MethodAnnotation getMethodCalledAnnotation​(org.apache.bcel.generic.ConstantPoolGen cpg,
                                                          org.apache.bcel.generic.InvokeInstruction inv)
      • getInvokedMethod

        public MethodDescriptor getInvokedMethod​(org.apache.bcel.generic.ConstantPoolGen cpg,
                                                 org.apache.bcel.generic.InvokeInstruction inv)
      • checkForWeirdEquals

        private boolean checkForWeirdEquals​(java.lang.String lhsSig,
                                            java.lang.String rhsSig,
                                            java.util.Set<XMethod> targets)
      • report

        public void report()
        Description copied from interface: Detector
        This method is called after all classes to be visited. It should be used by any detectors which accumulate information over all visited classes to generate results.
        Specified by:
        report in interface Detector