@@ -241,22 +241,26 @@ module CallGraph {
241241 )
242242 }
243243
244- private predicate shouldTrackObjectWithMethods ( DataFlow:: SourceNode node ) {
244+ private DataFlow :: FunctionNode getAMethodOnPlainObject ( DataFlow:: SourceNode node ) {
245245 (
246246 (
247247 node instanceof DataFlow:: ObjectLiteralNode
248248 or
249249 node instanceof DataFlow:: FunctionNode
250250 ) and
251- node .getAPropertySource ( ) instanceof DataFlow :: FunctionNode
251+ result = node .getAPropertySource ( )
252252 or
253- exists ( node .( DataFlow:: ObjectLiteralNode ) .getPropertyGetter ( _) )
253+ result = node .( DataFlow:: ObjectLiteralNode ) .getPropertyGetter ( _)
254254 or
255- exists ( node .( DataFlow:: ObjectLiteralNode ) .getPropertySetter ( _) )
255+ result = node .( DataFlow:: ObjectLiteralNode ) .getPropertySetter ( _)
256256 ) and
257257 not node .getTopLevel ( ) .isExterns ( )
258258 }
259259
260+ private predicate shouldTrackObjectWithMethods ( DataFlow:: SourceNode node ) {
261+ exists ( getAMethodOnPlainObject ( node ) )
262+ }
263+
260264 /**
261265 * Gets a step summary for tracking object literals.
262266 *
@@ -273,4 +277,22 @@ module CallGraph {
273277 or
274278 StepSummary:: step ( getAnAllocationSiteRef ( node ) , result , objectWithMethodsStep ( ) )
275279 }
280+
281+ /**
282+ * Holds if `pred` is assumed to flow to `succ` because a method is stored on an object that is assumed
283+ * to be the receiver of calls to that method.
284+ *
285+ * For example, object literal below is assumed to flow to the receiver of the `foo` function:
286+ * ```js
287+ * let obj = {};
288+ * obj.foo = function() {}
289+ * ```
290+ */
291+ cached
292+ predicate impliedReceiverStep ( DataFlow:: SourceNode pred , DataFlow:: SourceNode succ ) {
293+ exists ( DataFlow:: SourceNode host |
294+ pred = getAnAllocationSiteRef ( host ) and
295+ succ = getAMethodOnPlainObject ( host ) .getReceiver ( )
296+ )
297+ }
276298}
0 commit comments