Class ConstructorThrow

All Implemented Interfaces:
Detector, Priorities, org.apache.bcel.classfile.Visitor

public class ConstructorThrow extends OpcodeStackDetector
This detector can find constructors that throw exception.
  • Field Details

    • bugAccumulator

      private final BugAccumulator bugAccumulator
    • exHandlesToMethodCallsByMethodsMap

      private final Map<String,Map<String,Set<String>>> exHandlesToMethodCallsByMethodsMap
      The containing methods (DottedClassName complete with signature) to the methods called directly from the containing one to the caught Exceptions by the surrounding try-catches of the call sites. If the call site is not inside a try-catch then an empty string.
    • thrownExsByMethodMap

      private final Map<String,Set<org.apache.bcel.classfile.JavaClass>> thrownExsByMethodMap
      The DottedClassName complete with signature of the method to the set of the Exceptions thrown directly from the method.
    • isFinalClass

      private boolean isFinalClass
    • isFinalFinalizer

      private boolean isFinalFinalizer
    • isFirstPass

      private boolean isFirstPass
    • hadObjectConstructor

      private boolean hadObjectConstructor
  • Constructor Details

    • ConstructorThrow

      public ConstructorThrow(BugReporter bugReporter)
  • Method Details

    • visit

      public void visit(org.apache.bcel.classfile.JavaClass obj)
      Visit a class to find the constructor, then collect all the methods that gets called in it. Also, we are checking for final declaration on the class, or a final finalizer, as if present no finalizer attack can happen.
      Overrides:
      visit in class BetterVisitor
    • hasFinalFinalizer

      private static boolean hasFinalFinalizer(org.apache.bcel.classfile.JavaClass jc)
    • visitAfter

      public void visitAfter(org.apache.bcel.classfile.JavaClass obj)
      Overrides:
      visitAfter in class PreorderVisitor
    • sawOpcode

      public void sawOpcode(int seen)
      1. Check for any throw expression in the constructor. 2. Check for any exception throw inside constructor, or any of the called methods. If the class is final, we are fine, no finalizer attack can happen. In the first pass the detector shouldn't report, because there could be a final finalizer and a throwing constructor. Reporting in this case would be a false positive as classes with a final finalizer are not vulnerable to the finalizer attack.
      Specified by:
      sawOpcode in class OpcodeStackDetector
      See Also:
    • reportConstructorThrow

      private void reportConstructorThrow(int seen)
      Reports ConstructorThrow bug if there is an unhandled unchecked exception thrown directly or indirectly from the currently visited method. If the exception is thrown directly, the bug is reported at the throw. If the exception is thrown indirectly (through a method call), the bug is reported at the call of the method which throws the exception.
    • getUnhandledExThrowsInMethod

      private Set<org.apache.bcel.classfile.JavaClass> getUnhandledExThrowsInMethod(String method, Set<String> visitedMethods)
      Get the Exceptions thrown from the inside of the method, either directly or indirectly from called methods. Uses inner collections which are needed to filled correctly.
      Parameters:
      method - the method to visit and get the exceptions thrown out of it
      visitedMethods - the names of the already visited methods, needed to prevent stackoverflow by recursively checking method call cycles
      Returns:
      the JavaClasses of the Exceptions thrown from the method
    • isHandled

      private boolean isHandled(org.apache.bcel.classfile.JavaClass thrownEx, Set<String> exHandles)
      Checks whether the Exception is handled in all call sites.
      Parameters:
      thrownEx - the thrown Exception which needs to be handled
      exHandles - the set of the dotted class names of the caught Exceptions in the call sites.
      Returns:
      true if the Exception handled in all call sites.
    • isHandled

      private static boolean isHandled(org.apache.bcel.classfile.JavaClass thrownEx, @NonNull @DottedClassName String caughtEx)
      Checks if the thrown Exception is handled by the caught Exception.
      Parameters:
      thrownEx - the thrown Exception which needs to be handled
      caughtEx - the name of the caught Exception at the call site. If no Exception is caught, then it's an empty string or other nonnull string which is not a name of any Exception.
      Returns:
      true if the Exception is handled.
    • getSurroundingCaughtExes

      private Set<String> getSurroundingCaughtExes(org.apache.bcel.classfile.ConstantPool cp)
      Gets the DottedClassNames of the Exceptions which are caught by a try-catch block at the current PC.
      Parameters:
      cp - ConstantPool
      Returns:
      Set of the DottedClassNames of the caught Exceptions.
    • isThrownExNotCaught

      private static boolean isThrownExNotCaught(org.apache.bcel.classfile.JavaClass thrownEx, Set<String> caughtExes)
      Checks if the thrown exception is not caught.
      Parameters:
      thrownEx - the Exception to catch.
      caughtExes - the set of the DottedClassNames of the caught Exceptions at call site.
      Returns:
      true if the exception is not caught.
    • toDotted

      private static String toDotted(String signature)
    • collectExceptionsByMethods

      private void collectExceptionsByMethods(int seen)
      Fills the inner collections while visiting the method.
      Parameters:
      seen - the opcode @see #sawOpcode(int)
    • addToExHandlesToMethodCallsByMethodsMap

      private void addToExHandlesToMethodCallsByMethodsMap(String containerMethod, String calledMethod, Collection<String> caughtExes)
    • addToThrownExsByMethodMap

      private void addToThrownExsByMethodMap(String containingMethod, org.apache.bcel.classfile.JavaClass thrownExClass)
    • getCalledMethodFQN

      private String getCalledMethodFQN()
      Gives back the fully qualified name (DottedClassName) of the called method complete with the signature. Needs to be called from method call opcode.
      Returns:
      the fully qualified name of the method (dotted) with the signature.
    • resetState

      private void resetState()
    • accumulateBug

      private void accumulateBug()
    • isMethodCall

      private boolean isMethodCall(int seen)
    • isConstructor

      private boolean isConstructor()