diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll index 0e4db6a9a6e..4420faacbfe 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll @@ -263,34 +263,20 @@ module CallGraph { } /** - * Holds if `node` has methods but appears in a position where it might be an object - * with callbacks pased in via "named parmaeters". This avoid false flow, we do not allow - * such objects to be tracked into calls. + * Gets a step summary for tracking object literals. + * + * To avoid false flow from callbacks passed in via "named parameters", we only track object + * literals out of returns, not into calls. */ - pragma[nomagic] - private predicate isNamedParameterArgument(DataFlow::ObjectLiteralNode node) { - shouldTrackObjectWithMethods(node) and - node = any(DataFlow::InvokeNode invoke).getAnArgument() - } - - /** Gets a node that refers to the given object, via a limited form of type tracking. */ - private DataFlow::SourceNode getAnAllocationSiteRef( - DataFlow::SourceNode node, DataFlow::TypeTracker t - ) { - shouldTrackObjectWithMethods(node) and - result = node and - t.start() - or - exists(DataFlow::TypeTracker t2 | - result = getAnAllocationSiteRef(node, t2).track(t2, t) and - (if isNamedParameterArgument(node) then t.hasCall() = false else any()) - ) - } + private StepSummary objectWithMethodsStep() { result = LevelStep() or result = ReturnStep() } /** Gets a node that refers to the given object, via a limited form of type tracking. */ cached DataFlow::SourceNode getAnAllocationSiteRef(DataFlow::SourceNode node) { - result = getAnAllocationSiteRef(node, DataFlow::TypeTracker::end()) + shouldTrackObjectWithMethods(node) and + result = node + or + StepSummary::step(getAnAllocationSiteRef(node), result, objectWithMethodsStep()) } /**