diff --git a/javascript/ql/lib/semmle/javascript/Expr.qll b/javascript/ql/lib/semmle/javascript/Expr.qll index e8ec55f0174..83999627e78 100644 --- a/javascript/ql/lib/semmle/javascript/Expr.qll +++ b/javascript/ql/lib/semmle/javascript/Expr.qll @@ -4,6 +4,7 @@ import javascript private import semmle.javascript.internal.CachedStages +private import semmle.javascript.internal.TypeResolution /** * A program element that is either an expression or a type annotation. @@ -1017,7 +1018,11 @@ class InvokeExpr extends @invokeexpr, Expr { * Note that the resolved function may be overridden in a subclass and thus is not * necessarily the actual target of this invocation at runtime. */ - Function getResolvedCallee() { result = this.getResolvedCalleeName().getImplementation() } + Function getResolvedCallee() { + TypeResolution::callTarget(this, result) + or + result = this.getResolvedCalleeName().getImplementation() + } } /** diff --git a/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll b/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll index 4b482eddd89..4dc0bb44cd2 100644 --- a/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll +++ b/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll @@ -111,7 +111,7 @@ module TypeResolution { member.(AST::ValueNode).flow(), contents) } - private predicate callTarget(InvokeExpr call, Function target) { + predicate callTarget(InvokeExpr call, Function target) { exists(ClassDefinition cls | valueHasType(call.(NewExpr).getCallee(), trackClassValue(cls)) and target = cls.getConstructor().getBody()