diff --git a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql index 123515a7cbd3..7fa8e6ddf903 100644 --- a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql +++ b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql @@ -211,9 +211,9 @@ where msg = "the $@ does not return anything, yet the return value from the call to " + call.getCalleeName() + " is used." and name = "callback function" ) and - not benignContext(call.asExpr()) and + not benignContext(call.getEnclosingExpr()) and not lastStatementHasNoEffect(func) and // anonymous one-shot closure. Those are used in weird ways and we ignore them. - not oneshotClosure(call.asExpr()) + not oneshotClosure(call.getEnclosingExpr()) select call, msg, func, name diff --git a/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll index 07920cba3c93..1cd8286447fe 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll @@ -85,6 +85,18 @@ module DataFlow { /** Gets the expression corresponding to this data flow node, if any. */ Expr asExpr() { this = TValueNode(result) } + /** + * Gets the expression enclosing this data flow node. + * In most cases the result is the same as `asExpr()`, however this method + * additionally the `InvokeExpr` corresponding to reflective calls, and the `Parameter` + * for a `DataFlow::ParameterNode`. + */ + Expr getEnclosingExpr() { + result = asExpr() or + this = DataFlow::reflectiveCallNode(result) or + result = this.(ParameterNode).getParameter() + } + /** Gets the AST node corresponding to this data flow node, if any. */ ASTNode getAstNode() { none() } @@ -950,6 +962,16 @@ module DataFlow { * Gets a pseudo-node representing the root of a global access path. */ DataFlow::Node globalAccessPathRootPseudoNode() { result instanceof TGlobalAccessPathRoot } + + /** + * Gets a data flow node representing the underlying call performed by the given + * call to `Function.prototype.call` or `Function.prototype.apply`. + * + * For example, for an expression `fn.call(x, y)`, this gets a call node with `fn` as the + * callee, `x` as the receiver, and `y` as the first argument. + */ + DataFlow::InvokeNode reflectiveCallNode(InvokeExpr expr) { result = TReflectiveCallNode(expr, _) } + /** * Provides classes representing various kinds of calls. diff --git a/javascript/ql/test/library-tests/DataFlow/enclosingExpr.expected b/javascript/ql/test/library-tests/DataFlow/enclosingExpr.expected new file mode 100644 index 000000000000..b7da1347fce9 --- /dev/null +++ b/javascript/ql/test/library-tests/DataFlow/enclosingExpr.expected @@ -0,0 +1,321 @@ +| eval.js:1:10:1:10 | k | eval.js:1:10:1:10 | k | +| eval.js:2:7:2:7 | x | eval.js:2:7:2:7 | x | +| eval.js:2:7:2:12 | x = 42 | eval.js:2:7:2:12 | x = 42 | +| eval.js:2:11:2:12 | 42 | eval.js:2:11:2:12 | 42 | +| eval.js:3:3:3:6 | eval | eval.js:3:3:3:6 | eval | +| eval.js:3:3:3:16 | eval("x = 23") | eval.js:3:3:3:16 | eval("x = 23") | +| eval.js:3:8:3:15 | "x = 23" | eval.js:3:8:3:15 | "x = 23" | +| eval.js:4:3:4:3 | x | eval.js:4:3:4:3 | x | +| sources.js:1:1:1:12 | new (x => x) | sources.js:1:1:1:12 | new (x => x) | +| sources.js:1:5:1:12 | (x => x) | sources.js:1:5:1:12 | (x => x) | +| sources.js:1:6:1:6 | x | sources.js:1:6:1:6 | x | +| sources.js:1:6:1:6 | x | sources.js:1:6:1:6 | x | +| sources.js:1:6:1:11 | x => x | sources.js:1:6:1:11 | x => x | +| sources.js:1:11:1:11 | x | sources.js:1:11:1:11 | x | +| sources.js:3:1:5:2 | (functi ... +19;\\n}) | sources.js:3:1:5:2 | (functi ... +19;\\n}) | +| sources.js:3:1:5:6 | (functi ... \\n})(23) | sources.js:3:1:5:6 | (functi ... \\n})(23) | +| sources.js:3:2:5:1 | functio ... x+19;\\n} | sources.js:3:2:5:1 | functio ... x+19;\\n} | +| sources.js:3:11:3:11 | x | sources.js:3:11:3:11 | x | +| sources.js:3:11:3:11 | x | sources.js:3:11:3:11 | x | +| sources.js:4:10:4:10 | x | sources.js:4:10:4:10 | x | +| sources.js:4:10:4:13 | x+19 | sources.js:4:10:4:13 | x+19 | +| sources.js:4:12:4:13 | 19 | sources.js:4:12:4:13 | 19 | +| sources.js:5:4:5:5 | 23 | sources.js:5:4:5:5 | 23 | +| sources.js:7:1:7:3 | /x/ | sources.js:7:1:7:3 | /x/ | +| sources.js:9:10:9:12 | foo | sources.js:9:10:9:12 | foo | +| sources.js:9:14:9:18 | array | sources.js:9:14:9:18 | array | +| sources.js:9:14:9:18 | array | sources.js:9:14:9:18 | array | +| sources.js:10:12:10:14 | key | sources.js:10:12:10:14 | key | +| sources.js:10:12:10:14 | key | sources.js:10:12:10:14 | key | +| sources.js:10:19:10:23 | array | sources.js:10:19:10:23 | array | +| sources.js:10:28:10:30 | key | sources.js:10:28:10:30 | key | +| sources.js:11:12:11:18 | { key } | sources.js:11:12:11:18 | { key } | +| sources.js:11:12:11:18 | { key } | sources.js:11:12:11:18 | { key } | +| sources.js:11:14:11:16 | key | sources.js:11:14:11:16 | key | +| sources.js:11:14:11:16 | key | sources.js:11:14:11:16 | key | +| sources.js:11:23:11:27 | array | sources.js:11:23:11:27 | array | +| sources.js:11:32:11:34 | key | sources.js:11:32:11:34 | key | +| tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | +| tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | +| tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | +| tst.js:1:20:1:23 | 'fs' | tst.js:1:20:1:23 | 'fs' | +| tst.js:3:5:3:5 | x | tst.js:3:5:3:5 | x | +| tst.js:3:5:3:10 | x = 42 | tst.js:3:5:3:10 | x = 42 | +| tst.js:3:9:3:10 | 42 | tst.js:3:9:3:10 | 42 | +| tst.js:4:5:4:5 | y | tst.js:4:5:4:5 | y | +| tst.js:4:5:4:12 | y = "hi" | tst.js:4:5:4:12 | y = "hi" | +| tst.js:4:9:4:12 | "hi" | tst.js:4:9:4:12 | "hi" | +| tst.js:5:5:5:5 | z | tst.js:5:5:5:5 | z | +| tst.js:5:5:5:5 | z | tst.js:5:5:5:5 | z | +| tst.js:7:1:7:2 | fs | tst.js:7:1:7:2 | fs | +| tst.js:8:1:8:1 | x | tst.js:8:1:8:1 | x | +| tst.js:9:1:9:3 | (x) | tst.js:9:1:9:3 | (x) | +| tst.js:9:2:9:2 | x | tst.js:9:2:9:2 | x | +| tst.js:10:1:10:1 | x | tst.js:10:1:10:1 | x | +| tst.js:10:1:10:4 | x, y | tst.js:10:1:10:4 | x, y | +| tst.js:10:4:10:4 | y | tst.js:10:4:10:4 | y | +| tst.js:11:1:11:1 | x | tst.js:11:1:11:1 | x | +| tst.js:11:1:11:6 | x && y | tst.js:11:1:11:6 | x && y | +| tst.js:11:6:11:6 | y | tst.js:11:6:11:6 | y | +| tst.js:12:1:12:1 | x | tst.js:12:1:12:1 | x | +| tst.js:12:1:12:6 | x \|\| y | tst.js:12:1:12:6 | x \|\| y | +| tst.js:12:6:12:6 | y | tst.js:12:6:12:6 | y | +| tst.js:13:1:13:1 | z | tst.js:13:1:13:1 | z | +| tst.js:13:1:13:5 | z = y | tst.js:13:1:13:5 | z = y | +| tst.js:13:5:13:5 | y | tst.js:13:5:13:5 | y | +| tst.js:14:1:14:1 | z | tst.js:14:1:14:1 | z | +| tst.js:14:1:14:9 | z ? x : y | tst.js:14:1:14:9 | z ? x : y | +| tst.js:14:5:14:5 | x | tst.js:14:5:14:5 | x | +| tst.js:14:9:14:9 | y | tst.js:14:9:14:9 | y | +| tst.js:16:1:20:2 | (functi ... "";\\n}) | tst.js:16:1:20:2 | (functi ... "";\\n}) | +| tst.js:16:1:20:9 | (functi ... ("arg") | tst.js:16:1:20:9 | (functi ... ("arg") | +| tst.js:16:2:20:1 | functio ... n "";\\n} | tst.js:16:2:20:1 | functio ... n "";\\n} | +| tst.js:16:11:16:11 | f | tst.js:16:11:16:11 | f | +| tst.js:16:13:16:13 | a | tst.js:16:13:16:13 | a | +| tst.js:16:13:16:13 | a | tst.js:16:13:16:13 | a | +| tst.js:17:7:17:10 | Math | tst.js:17:7:17:10 | Math | +| tst.js:17:7:17:17 | Math.random | tst.js:17:7:17:17 | Math.random | +| tst.js:17:7:17:19 | Math.random() | tst.js:17:7:17:19 | Math.random() | +| tst.js:17:7:17:25 | Math.random() > 0.5 | tst.js:17:7:17:25 | Math.random() > 0.5 | +| tst.js:17:12:17:17 | random | tst.js:17:12:17:17 | random | +| tst.js:17:23:17:25 | 0.5 | tst.js:17:23:17:25 | 0.5 | +| tst.js:18:12:18:12 | a | tst.js:18:12:18:12 | a | +| tst.js:19:10:19:11 | "" | tst.js:19:10:19:11 | "" | +| tst.js:20:4:20:8 | "arg" | tst.js:20:4:20:8 | "arg" | +| tst.js:22:5:22:20 | { readFileSync } | tst.js:22:5:22:20 | { readFileSync } | +| tst.js:22:5:22:25 | { readF ... } = fs | tst.js:22:5:22:25 | { readF ... } = fs | +| tst.js:22:7:22:18 | readFileSync | tst.js:22:7:22:18 | readFileSync | +| tst.js:22:7:22:18 | readFileSync | tst.js:22:7:22:18 | readFileSync | +| tst.js:22:24:22:25 | fs | tst.js:22:24:22:25 | fs | +| tst.js:23:1:23:12 | readFileSync | tst.js:23:1:23:12 | readFileSync | +| tst.js:25:1:25:3 | ++x | tst.js:25:1:25:3 | ++x | +| tst.js:25:3:25:3 | x | tst.js:25:3:25:3 | x | +| tst.js:26:1:26:1 | x | tst.js:26:1:26:1 | x | +| tst.js:28:1:30:1 | (() =>\\n ... ables\\n) | tst.js:28:1:30:1 | (() =>\\n ... ables\\n) | +| tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | +| tst.js:28:2:29:3 | () =>\\n x | tst.js:28:2:29:3 | () =>\\n x | +| tst.js:29:3:29:3 | x | tst.js:29:3:29:3 | x | +| tst.js:32:10:32:10 | g | tst.js:32:10:32:10 | g | +| tst.js:32:12:32:12 | b | tst.js:32:12:32:12 | b | +| tst.js:32:12:32:12 | b | tst.js:32:12:32:12 | b | +| tst.js:33:10:33:10 | x | tst.js:33:10:33:10 | x | +| tst.js:35:1:35:1 | g | tst.js:35:1:35:1 | g | +| tst.js:35:1:35:7 | g(true) | tst.js:35:1:35:7 | g(true) | +| tst.js:35:3:35:6 | true | tst.js:35:3:35:6 | true | +| tst.js:37:5:37:5 | o | tst.js:37:5:37:5 | o | +| tst.js:37:5:42:1 | o = {\\n ... ;\\n }\\n} | tst.js:37:5:42:1 | o = {\\n ... ;\\n }\\n} | +| tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} | tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} | +| tst.js:38:3:38:3 | x | tst.js:38:3:38:3 | x | +| tst.js:38:6:38:9 | null | tst.js:38:6:38:9 | null | +| tst.js:39:3:39:3 | m | tst.js:39:3:39:3 | m | +| tst.js:39:4:41:3 | () {\\n this;\\n } | tst.js:39:4:41:3 | () {\\n this;\\n } | +| tst.js:40:5:40:8 | this | tst.js:40:5:40:8 | this | +| tst.js:43:1:43:1 | o | tst.js:43:1:43:1 | o | +| tst.js:43:1:43:3 | o.x | tst.js:43:1:43:3 | o.x | +| tst.js:43:3:43:3 | x | tst.js:43:3:43:3 | x | +| tst.js:44:1:44:1 | o | tst.js:44:1:44:1 | o | +| tst.js:44:1:44:3 | o.m | tst.js:44:1:44:3 | o.m | +| tst.js:44:1:44:5 | o.m() | tst.js:44:1:44:5 | o.m() | +| tst.js:44:3:44:3 | m | tst.js:44:3:44:3 | m | +| tst.js:46:1:46:6 | global | tst.js:46:1:46:6 | global | +| tst.js:46:1:46:11 | global = "" | tst.js:46:1:46:11 | global = "" | +| tst.js:46:10:46:11 | "" | tst.js:46:10:46:11 | "" | +| tst.js:47:1:47:6 | global | tst.js:47:1:47:6 | global | +| tst.js:49:7:49:7 | A | tst.js:49:7:49:7 | A | +| tst.js:49:17:49:17 | B | tst.js:49:17:49:17 | B | +| tst.js:50:3:50:13 | constructor | tst.js:50:3:50:13 | constructor | +| tst.js:50:14:53:3 | () {\\n ... et`\\n } | tst.js:50:14:53:3 | () {\\n ... et`\\n } | +| tst.js:51:5:51:9 | super | tst.js:51:5:51:9 | super | +| tst.js:51:5:51:13 | super(42) | tst.js:51:5:51:13 | super(42) | +| tst.js:51:11:51:12 | 42 | tst.js:51:11:51:12 | 42 | +| tst.js:52:5:52:14 | new.target | tst.js:52:5:52:14 | new.target | +| tst.js:55:1:55:1 | A | tst.js:55:1:55:1 | A | +| tst.js:57:1:57:9 | `x: ${x}` | tst.js:57:1:57:9 | `x: ${x}` | +| tst.js:57:2:57:4 | x: | tst.js:57:2:57:4 | x: | +| tst.js:57:7:57:7 | x | tst.js:57:7:57:7 | x | +| tst.js:58:1:58:3 | tag | tst.js:58:1:58:3 | tag | +| tst.js:58:1:58:13 | tag `x: ${x}` | tst.js:58:1:58:13 | tag `x: ${x}` | +| tst.js:58:5:58:13 | `x: ${x}` | tst.js:58:5:58:13 | `x: ${x}` | +| tst.js:58:6:58:8 | x: | tst.js:58:6:58:8 | x: | +| tst.js:58:11:58:11 | x | tst.js:58:11:58:11 | x | +| tst.js:60:1:60:1 | g | tst.js:60:1:60:1 | g | +| tst.js:61:1:61:5 | ::o.m | tst.js:61:1:61:5 | ::o.m | +| tst.js:61:3:61:3 | o | tst.js:61:3:61:3 | o | +| tst.js:61:3:61:5 | o.m | tst.js:61:3:61:5 | o.m | +| tst.js:61:5:61:5 | m | tst.js:61:5:61:5 | m | +| tst.js:62:1:62:1 | o | tst.js:62:1:62:1 | o | +| tst.js:62:1:62:4 | o::g | tst.js:62:1:62:4 | o::g | +| tst.js:62:4:62:4 | g | tst.js:62:4:62:4 | g | +| tst.js:64:11:64:11 | h | tst.js:64:11:64:11 | h | +| tst.js:65:3:65:10 | yield 42 | tst.js:65:3:65:10 | yield 42 | +| tst.js:65:9:65:10 | 42 | tst.js:65:9:65:10 | 42 | +| tst.js:66:7:66:9 | tmp | tst.js:66:7:66:9 | tmp | +| tst.js:66:7:66:25 | tmp = function.sent | tst.js:66:7:66:25 | tmp = function.sent | +| tst.js:66:13:66:25 | function.sent | tst.js:66:13:66:25 | function.sent | +| tst.js:68:5:68:8 | iter | tst.js:68:5:68:8 | iter | +| tst.js:68:5:68:14 | iter = h() | tst.js:68:5:68:14 | iter = h() | +| tst.js:68:12:68:12 | h | tst.js:68:12:68:12 | h | +| tst.js:68:12:68:14 | h() | tst.js:68:12:68:14 | h() | +| tst.js:69:1:69:4 | iter | tst.js:69:1:69:4 | iter | +| tst.js:69:1:69:9 | iter.next | tst.js:69:1:69:9 | iter.next | +| tst.js:69:1:69:13 | iter.next(23) | tst.js:69:1:69:13 | iter.next(23) | +| tst.js:69:6:69:9 | next | tst.js:69:6:69:9 | next | +| tst.js:69:11:69:12 | 23 | tst.js:69:11:69:12 | 23 | +| tst.js:71:16:71:16 | k | tst.js:71:16:71:16 | k | +| tst.js:72:3:72:11 | await p() | tst.js:72:3:72:11 | await p() | +| tst.js:72:9:72:9 | p | tst.js:72:9:72:9 | p | +| tst.js:72:9:72:11 | p() | tst.js:72:9:72:11 | p() | +| tst.js:75:5:75:5 | m | tst.js:75:5:75:5 | m | +| tst.js:75:5:75:21 | m = import('foo') | tst.js:75:5:75:21 | m = import('foo') | +| tst.js:75:9:75:21 | import('foo') | tst.js:75:9:75:21 | import('foo') | +| tst.js:75:16:75:20 | 'foo' | tst.js:75:16:75:20 | 'foo' | +| tst.js:77:10:77:10 | i | tst.js:77:10:77:10 | i | +| tst.js:77:10:77:10 | i | tst.js:77:10:77:10 | i | +| tst.js:77:15:77:15 | o | tst.js:77:15:77:15 | o | +| tst.js:78:3:78:3 | i | tst.js:78:3:78:3 | i | +| tst.js:80:10:80:10 | v | tst.js:80:10:80:10 | v | +| tst.js:80:10:80:10 | v | tst.js:80:10:80:10 | v | +| tst.js:80:15:80:15 | o | tst.js:80:15:80:15 | o | +| tst.js:81:3:81:3 | v | tst.js:81:3:81:3 | v | +| tst.js:83:5:83:7 | vs1 | tst.js:83:5:83:7 | vs1 | +| tst.js:83:5:83:28 | vs1 = [ ... o) v ] | tst.js:83:5:83:28 | vs1 = [ ... o) v ] | +| tst.js:83:11:83:28 | [ for (v of o) v ] | tst.js:83:11:83:28 | [ for (v of o) v ] | +| tst.js:83:13:83:24 | for (v of o) | tst.js:83:13:83:24 | for (v of o) | +| tst.js:83:18:83:18 | v | tst.js:83:18:83:18 | v | +| tst.js:83:23:83:23 | o | tst.js:83:23:83:23 | o | +| tst.js:83:26:83:26 | v | tst.js:83:26:83:26 | v | +| tst.js:85:5:85:7 | vs2 | tst.js:85:5:85:7 | vs2 | +| tst.js:85:5:85:28 | vs2 = ( ... o) v ) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | +| tst.js:85:11:85:28 | ( for (v of o) v ) | tst.js:85:11:85:28 | ( for (v of o) v ) | +| tst.js:85:13:85:24 | for (v of o) | tst.js:85:13:85:24 | for (v of o) | +| tst.js:85:18:85:18 | v | tst.js:85:18:85:18 | v | +| tst.js:85:23:85:23 | o | tst.js:85:23:85:23 | o | +| tst.js:85:26:85:26 | v | tst.js:85:26:85:26 | v | +| tst.js:87:1:92:2 | (functi ... + z;\\n}) | tst.js:87:1:92:2 | (functi ... + z;\\n}) | +| tst.js:87:1:96:2 | (functi ... r: 0\\n}) | tst.js:87:1:96:2 | (functi ... r: 0\\n}) | +| tst.js:87:2:92:1 | functio ... + z;\\n} | tst.js:87:2:92:1 | functio ... + z;\\n} | +| tst.js:87:11:87:24 | { p: x, ...o } | tst.js:87:11:87:24 | { p: x, ...o } | +| tst.js:87:11:87:24 | { p: x, ...o } | tst.js:87:11:87:24 | { p: x, ...o } | +| tst.js:87:13:87:13 | p | tst.js:87:13:87:13 | p | +| tst.js:87:16:87:16 | x | tst.js:87:16:87:16 | x | +| tst.js:87:22:87:22 | o | tst.js:87:22:87:22 | o | +| tst.js:88:7:88:14 | { q: y } | tst.js:88:7:88:14 | { q: y } | +| tst.js:88:7:88:18 | { q: y } = o | tst.js:88:7:88:18 | { q: y } = o | +| tst.js:88:9:88:9 | q | tst.js:88:9:88:9 | q | +| tst.js:88:12:88:12 | y | tst.js:88:12:88:12 | y | +| tst.js:88:18:88:18 | o | tst.js:88:18:88:18 | o | +| tst.js:89:7:89:7 | z | tst.js:89:7:89:7 | z | +| tst.js:89:7:89:7 | z | tst.js:89:7:89:7 | z | +| tst.js:90:3:90:16 | ({ r: z } = o) | tst.js:90:3:90:16 | ({ r: z } = o) | +| tst.js:90:4:90:11 | { r: z } | tst.js:90:4:90:11 | { r: z } | +| tst.js:90:4:90:15 | { r: z } = o | tst.js:90:4:90:15 | { r: z } = o | +| tst.js:90:6:90:6 | r | tst.js:90:6:90:6 | r | +| tst.js:90:9:90:9 | z | tst.js:90:9:90:9 | z | +| tst.js:90:15:90:15 | o | tst.js:90:15:90:15 | o | +| tst.js:91:10:91:10 | x | tst.js:91:10:91:10 | x | +| tst.js:91:10:91:14 | x + y | tst.js:91:10:91:14 | x + y | +| tst.js:91:10:91:18 | x + y + z | tst.js:91:10:91:18 | x + y + z | +| tst.js:91:14:91:14 | y | tst.js:91:14:91:14 | y | +| tst.js:91:18:91:18 | z | tst.js:91:18:91:18 | z | +| tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} | tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} | +| tst.js:93:3:93:3 | p | tst.js:93:3:93:3 | p | +| tst.js:93:6:93:7 | 19 | tst.js:93:6:93:7 | 19 | +| tst.js:94:3:94:3 | q | tst.js:94:3:94:3 | q | +| tst.js:94:6:94:7 | 23 | tst.js:94:6:94:7 | 23 | +| tst.js:95:3:95:3 | r | tst.js:95:3:95:3 | r | +| tst.js:95:6:95:6 | 0 | tst.js:95:6:95:6 | 0 | +| tst.js:98:1:103:2 | (functi ... + z;\\n}) | tst.js:98:1:103:2 | (functi ... + z;\\n}) | +| tst.js:98:1:103:17 | (functi ... 3, 0 ]) | tst.js:98:1:103:17 | (functi ... 3, 0 ]) | +| tst.js:98:2:103:1 | functio ... + z;\\n} | tst.js:98:2:103:1 | functio ... + z;\\n} | +| tst.js:98:11:98:24 | [ x, ...rest ] | tst.js:98:11:98:24 | [ x, ...rest ] | +| tst.js:98:11:98:24 | [ x, ...rest ] | tst.js:98:11:98:24 | [ x, ...rest ] | +| tst.js:98:13:98:13 | x | tst.js:98:13:98:13 | x | +| tst.js:98:19:98:22 | rest | tst.js:98:19:98:22 | rest | +| tst.js:99:7:99:11 | [ y ] | tst.js:99:7:99:11 | [ y ] | +| tst.js:99:7:99:18 | [ y ] = rest | tst.js:99:7:99:18 | [ y ] = rest | +| tst.js:99:9:99:9 | y | tst.js:99:9:99:9 | y | +| tst.js:99:15:99:18 | rest | tst.js:99:15:99:18 | rest | +| tst.js:100:7:100:7 | z | tst.js:100:7:100:7 | z | +| tst.js:100:7:100:7 | z | tst.js:100:7:100:7 | z | +| tst.js:101:3:101:9 | [ , z ] | tst.js:101:3:101:9 | [ , z ] | +| tst.js:101:3:101:16 | [ , z ] = rest | tst.js:101:3:101:16 | [ , z ] = rest | +| tst.js:101:7:101:7 | z | tst.js:101:7:101:7 | z | +| tst.js:101:13:101:16 | rest | tst.js:101:13:101:16 | rest | +| tst.js:102:10:102:10 | x | tst.js:102:10:102:10 | x | +| tst.js:102:10:102:14 | x + y | tst.js:102:10:102:14 | x + y | +| tst.js:102:10:102:18 | x + y + z | tst.js:102:10:102:18 | x + y + z | +| tst.js:102:14:102:14 | y | tst.js:102:14:102:14 | y | +| tst.js:102:18:102:18 | z | tst.js:102:18:102:18 | z | +| tst.js:103:4:103:16 | [ 19, 23, 0 ] | tst.js:103:4:103:16 | [ 19, 23, 0 ] | +| tst.js:103:6:103:7 | 19 | tst.js:103:6:103:7 | 19 | +| tst.js:103:10:103:11 | 23 | tst.js:103:10:103:11 | 23 | +| tst.js:103:14:103:14 | 0 | tst.js:103:14:103:14 | 0 | +| tst.js:105:1:105:1 | x | tst.js:105:1:105:1 | x | +| tst.js:105:1:105:6 | x ?? y | tst.js:105:1:105:6 | x ?? y | +| tst.js:105:6:105:6 | y | tst.js:105:6:105:6 | y | +| tst.js:107:1:113:2 | (functi ... v2c;\\n}) | tst.js:107:1:113:2 | (functi ... v2c;\\n}) | +| tst.js:107:2:113:1 | functio ... v2c;\\n} | tst.js:107:2:113:1 | functio ... v2c;\\n} | +| tst.js:108:6:108:32 | {v1a, v ... = o1c} | tst.js:108:6:108:32 | {v1a, v ... = o1c} | +| tst.js:108:6:108:38 | {v1a, v ... } = o1d | tst.js:108:6:108:38 | {v1a, v ... } = o1d | +| tst.js:108:7:108:9 | v1a | tst.js:108:7:108:9 | v1a | +| tst.js:108:7:108:9 | v1a | tst.js:108:7:108:9 | v1a | +| tst.js:108:12:108:14 | v1b | tst.js:108:12:108:14 | v1b | +| tst.js:108:12:108:14 | v1b | tst.js:108:12:108:14 | v1b | +| tst.js:108:18:108:20 | o1b | tst.js:108:18:108:20 | o1b | +| tst.js:108:23:108:25 | v1c | tst.js:108:23:108:25 | v1c | +| tst.js:108:23:108:25 | v1c | tst.js:108:23:108:25 | v1c | +| tst.js:108:29:108:31 | o1c | tst.js:108:29:108:31 | o1c | +| tst.js:108:36:108:38 | o1d | tst.js:108:36:108:38 | o1d | +| tst.js:109:2:109:4 | v1a | tst.js:109:2:109:4 | v1a | +| tst.js:109:2:109:10 | v1a + v1b | tst.js:109:2:109:10 | v1a + v1b | +| tst.js:109:2:109:16 | v1a + v1b + v1c | tst.js:109:2:109:16 | v1a + v1b + v1c | +| tst.js:109:8:109:10 | v1b | tst.js:109:8:109:10 | v1b | +| tst.js:109:14:109:16 | v1c | tst.js:109:14:109:16 | v1c | +| tst.js:111:6:111:32 | [v2a, v ... = o2c] | tst.js:111:6:111:32 | [v2a, v ... = o2c] | +| tst.js:111:6:111:38 | [v2a, v ... ] = o2d | tst.js:111:6:111:38 | [v2a, v ... ] = o2d | +| tst.js:111:7:111:9 | v2a | tst.js:111:7:111:9 | v2a | +| tst.js:111:12:111:14 | v2b | tst.js:111:12:111:14 | v2b | +| tst.js:111:18:111:20 | o2b | tst.js:111:18:111:20 | o2b | +| tst.js:111:23:111:25 | v2c | tst.js:111:23:111:25 | v2c | +| tst.js:111:29:111:31 | o2c | tst.js:111:29:111:31 | o2c | +| tst.js:111:36:111:38 | o2d | tst.js:111:36:111:38 | o2d | +| tst.js:112:2:112:4 | v2a | tst.js:112:2:112:4 | v2a | +| tst.js:112:2:112:10 | v2a + v2b | tst.js:112:2:112:10 | v2a + v2b | +| tst.js:112:2:112:16 | v2a + v2b + v2c | tst.js:112:2:112:16 | v2a + v2b + v2c | +| tst.js:112:8:112:10 | v2b | tst.js:112:8:112:10 | v2b | +| tst.js:112:14:112:16 | v2c | tst.js:112:14:112:16 | v2c | +| tst.js:115:1:115:5 | Array | tst.js:115:1:115:5 | Array | +| tst.js:115:1:115:10 | Array.call | tst.js:115:1:115:10 | Array.call | +| tst.js:115:1:115:12 | Array.call() | tst.js:115:1:115:12 | Array.call() | +| tst.js:115:1:115:12 | reflective call | tst.js:115:1:115:12 | Array.call() | +| tst.js:115:7:115:10 | call | tst.js:115:7:115:10 | call | +| tst.ts:1:18:1:18 | A | tst.ts:1:18:1:18 | A | +| tst.ts:2:14:2:14 | x | tst.ts:2:14:2:14 | x | +| tst.ts:2:14:2:19 | x = 42 | tst.ts:2:14:2:19 | x = 42 | +| tst.ts:2:18:2:19 | 42 | tst.ts:2:18:2:19 | 42 | +| tst.ts:3:3:3:6 | setX | tst.ts:3:3:3:6 | setX | +| tst.ts:3:3:3:8 | setX() | tst.ts:3:3:3:8 | setX() | +| tst.ts:4:3:4:3 | x | tst.ts:4:3:4:3 | x | +| tst.ts:7:10:7:13 | setX | tst.ts:7:10:7:13 | setX | +| tst.ts:8:3:8:3 | A | tst.ts:8:3:8:3 | A | +| tst.ts:8:3:8:5 | A.x | tst.ts:8:3:8:5 | A.x | +| tst.ts:8:3:8:10 | A.x = 23 | tst.ts:8:3:8:10 | A.x = 23 | +| tst.ts:8:5:8:5 | x | tst.ts:8:5:8:5 | x | +| tst.ts:8:9:8:10 | 23 | tst.ts:8:9:8:10 | 23 | +| tst.ts:11:5:11:7 | nd2 | tst.ts:11:5:11:7 | nd2 | +| tst.ts:11:5:11:23 | nd2 = A.x as number | tst.ts:11:5:11:23 | nd2 = A.x as number | +| tst.ts:11:11:11:11 | A | tst.ts:11:11:11:11 | A | +| tst.ts:11:11:11:13 | A.x | tst.ts:11:11:11:13 | A.x | +| tst.ts:11:11:11:23 | A.x as number | tst.ts:11:11:11:23 | A.x as number | +| tst.ts:11:13:11:13 | x | tst.ts:11:13:11:13 | x | +| tst.ts:13:7:13:16 | StringList | tst.ts:13:7:13:16 | StringList | +| tst.ts:13:26:13:29 | List | tst.ts:13:26:13:29 | List | +| tst.ts:13:26:13:37 | List | tst.ts:13:26:13:37 | List | +| tst.ts:13:39:13:38 | (...arg ... rgs); } | tst.ts:13:39:13:38 | (...arg ... rgs); } | +| tst.ts:13:39:13:38 | ...args | tst.ts:13:39:13:38 | ...args | +| tst.ts:13:39:13:38 | args | tst.ts:13:39:13:38 | args | +| tst.ts:13:39:13:38 | args | tst.ts:13:39:13:38 | args | +| tst.ts:13:39:13:38 | args | tst.ts:13:39:13:38 | args | +| tst.ts:13:39:13:38 | constructor | tst.ts:13:39:13:38 | constructor | +| tst.ts:13:39:13:38 | super | tst.ts:13:39:13:38 | super | +| tst.ts:13:39:13:38 | super(...args) | tst.ts:13:39:13:38 | super(...args) | diff --git a/javascript/ql/test/library-tests/DataFlow/enclosingExpr.ql b/javascript/ql/test/library-tests/DataFlow/enclosingExpr.ql new file mode 100644 index 000000000000..6b0a506ce798 --- /dev/null +++ b/javascript/ql/test/library-tests/DataFlow/enclosingExpr.ql @@ -0,0 +1,4 @@ +import javascript + +from DataFlow::Node node +select node, node.getEnclosingExpr()