@@ -1683,4 +1683,59 @@ module DataFlow {
16831683 import TypeTracking
16841684
16851685 predicate localTaintStep = TaintTracking:: localTaintStep / 2 ;
1686+
1687+ /**
1688+ * Holds if the function in `succ` forwards all its arguments to a call to `pred` and returns
1689+ * its result. This can thus be seen as a step `pred -> succ` used for tracking function values
1690+ * through "wrapper functions", since the `succ` function partially replicates behavior of `pred`.
1691+ *
1692+ * Examples:
1693+ * ```js
1694+ * function f(x) {
1695+ * return g(x); // step: g -> f
1696+ * }
1697+ *
1698+ * function doExec(x) {
1699+ * console.log(x);
1700+ * return exec(x); // step: exec -> doExec
1701+ * }
1702+ *
1703+ * function doEither(x, y) {
1704+ * if (x > y) {
1705+ * return foo(x, y); // step: foo -> doEither
1706+ * } else {
1707+ * return bar(x, y); // step: bar -> doEither
1708+ * }
1709+ * }
1710+ *
1711+ * function wrapWithLogging(f) {
1712+ * return (x) => {
1713+ * console.log(x);
1714+ * return f(x); // step: f -> anonymous function
1715+ * }
1716+ * }
1717+ * wrapWithLogging(g); // step: g -> wrapWithLogging(g)
1718+ * ```
1719+ */
1720+ predicate functionForwardingStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
1721+ exists ( DataFlow:: FunctionNode function , DataFlow:: CallNode call |
1722+ call .flowsTo ( function .getReturnNode ( ) ) and
1723+ forall ( int i | exists ( [ call .getArgument ( i ) , function .getParameter ( i ) ] ) |
1724+ function .getParameter ( i ) .flowsTo ( call .getArgument ( i ) )
1725+ ) and
1726+ pred = call .getCalleeNode ( ) and
1727+ succ = function
1728+ )
1729+ or
1730+ // Given a generic wrapper function like,
1731+ //
1732+ // function wrap(f) { return (x, y) => f(x, y) };
1733+ //
1734+ // add steps through calls to that function: `g -> wrap(g)`
1735+ exists ( DataFlow:: FunctionNode wrapperFunction , SourceNode param , Node paramUse |
1736+ FlowSteps:: argumentPassing ( succ , pred , wrapperFunction .getFunction ( ) , param ) and
1737+ param .flowsTo ( paramUse ) and
1738+ functionForwardingStep ( paramUse , wrapperFunction .getReturnNode ( ) .getALocalSource ( ) )
1739+ )
1740+ }
16861741}
0 commit comments