@@ -434,7 +434,7 @@ private module CachedSteps {
434434 * invocation.
435435 */
436436 cached
437- predicate callback ( DataFlow:: Node arg , DataFlow:: SourceNode cb ) {
437+ predicate exploratoryCallbackStep ( DataFlow:: Node arg , DataFlow:: SourceNode cb ) {
438438 Stages:: TypeTracking:: ref ( ) and
439439 exists ( DataFlow:: InvokeNode invk , DataFlow:: ParameterNode cbParm , DataFlow:: Node cbArg |
440440 arg = invk .getAnArgument ( ) and
@@ -444,12 +444,24 @@ private module CachedSteps {
444444 )
445445 or
446446 exists ( DataFlow:: ParameterNode cbParm , DataFlow:: Node cbArg |
447- callback ( arg , cbParm ) and
447+ exploratoryCallbackStep ( arg , cbParm ) and
448448 callStep ( cbArg , cbParm ) and
449449 cb .flowsTo ( cbArg )
450450 )
451451 }
452452
453+ /** Gets a function that flows to `parameter` via one or more parameter-passing steps. */
454+ cached
455+ DataFlow:: FunctionNode getACallbackSource ( DataFlow:: ParameterNode parameter ) {
456+ Stages:: TypeTracking:: ref ( ) and
457+ callStep ( result .getALocalUse ( ) , parameter )
458+ or
459+ exists ( DataFlow:: ParameterNode mid |
460+ callStep ( mid .getALocalUse ( ) , parameter ) and
461+ result = getACallbackSource ( mid )
462+ )
463+ }
464+
453465 /**
454466 * Holds if `f` may return `base`, which has a write of property `prop` with right-hand side `rhs`.
455467 */
0 commit comments