diff --git a/javascript/ql/lib/change-notes/2024-11-15-toSpliced-support.md b/javascript/ql/lib/change-notes/2024-11-15-toSpliced-support.md new file mode 100644 index 000000000000..a73955e5d2a0 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-15-toSpliced-support.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +Added taint-steps for `Array.prototype.toSpliced` diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index d4360072aa28..933339b97882 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -81,12 +81,23 @@ module ArrayTaintTracking { pred = call.getArgument(any(int i | i >= 2)) and succ.(DataFlow::SourceNode).getAMethodCall("splice") = call or + // `array.toSpliced(x, y, source())`: if `source()` is tainted, then so is the result of `toSpliced`, but not the original array. + call.(DataFlow::MethodCallNode).getMethodName() = "toSpliced" and + pred = call.getArgument(any(int i | i >= 2)) and + succ = call + or // `array.splice(i, del, ...e)`: if `e` is tainted, then so is `array`. pred = call.getASpreadArgument() and succ.(DataFlow::SourceNode).getAMethodCall("splice") = call or + // `array.toSpliced(i, del, ...e)`: if `e` is tainted, then so is the result of `toSpliced`, but not the original array. + pred = call.getASpreadArgument() and + call.(DataFlow::MethodCallNode).getMethodName() = "toSpliced" and + succ = call + or // `e = array.pop()`, `e = array.shift()`, or similar: if `array` is tainted, then so is `e`. - call.(DataFlow::MethodCallNode).calls(pred, ["pop", "shift", "slice", "splice", "at"]) and + call.(DataFlow::MethodCallNode) + .calls(pred, ["pop", "shift", "slice", "splice", "at", "toSpliced"]) and succ = call or // `e = Array.from(x)`: if `x` is tainted, then so is `e`. @@ -283,7 +294,7 @@ private module ArrayDataFlow { private class ArraySpliceStep extends PreCallGraphStep { override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) { exists(DataFlow::MethodCallNode call | - call.getMethodName() = "splice" and + call.getMethodName() = ["splice", "toSpliced"] and prop = arrayElement() and element = call.getArgument(any(int i | i >= 2)) and call = obj.getAMethodCall() @@ -297,7 +308,7 @@ private module ArrayDataFlow { toProp = arrayElement() and // `array.splice(i, del, ...arr)` variant exists(DataFlow::MethodCallNode mcn | - mcn.getMethodName() = "splice" and + mcn.getMethodName() = ["splice", "toSpliced"] and pred = mcn.getASpreadArgument() and succ = mcn.getReceiver().getALocalSource() ) @@ -320,12 +331,12 @@ private module ArrayDataFlow { } /** - * A step for modeling that elements from an array `arr` also appear in the result from calling `slice`/`splice`/`filter`. + * A step for modeling that elements from an array `arr` also appear in the result from calling `slice`/`splice`/`filter`/`toSpliced`. */ private class ArraySliceStep extends PreCallGraphStep { override predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) { exists(DataFlow::MethodCallNode call | - call.getMethodName() = ["slice", "splice", "filter"] and + call.getMethodName() = ["slice", "splice", "filter", "toSpliced"] and prop = arrayElement() and pred = call.getReceiver() and succ = call diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index df0f76e7cda6..dc7b0190c916 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -972,7 +972,7 @@ private predicate isUsedAsNumber(DataFlow::LocalSourceNode value) { or exists(DataFlow::CallNode call | call.getCalleeName() = - ["substring", "substr", "slice", "splice", "charAt", "charCodeAt", "codePointAt"] and + ["substring", "substr", "slice", "splice", "charAt", "charCodeAt", "codePointAt", "toSpliced"] and value.flowsTo(call.getAnArgument()) ) } diff --git a/javascript/ql/test/library-tests/Arrays/DataFlow.expected b/javascript/ql/test/library-tests/Arrays/DataFlow.expected index 6de9bf77257a..4332f14c45e2 100644 --- a/javascript/ql/test/library-tests/Arrays/DataFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/DataFlow.expected @@ -13,6 +13,7 @@ | arrays.js:2:16:2:23 | "source" | arrays.js:86:8:86:35 | arrayFi ... llback) | | arrays.js:2:16:2:23 | "source" | arrays.js:90:10:90:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:93:8:93:17 | arr.at(-1) | +| arrays.js:2:16:2:23 | "source" | arrays.js:109:8:109:24 | arr8_spread.pop() | | arrays.js:18:22:18:29 | "source" | arrays.js:18:50:18:50 | e | | arrays.js:22:15:22:22 | "source" | arrays.js:23:8:23:17 | arr2.pop() | | arrays.js:25:15:25:22 | "source" | arrays.js:26:8:26:17 | arr3.pop() | @@ -22,3 +23,5 @@ | arrays.js:29:21:29:28 | "source" | arrays.js:50:8:50:17 | arr6.pop() | | arrays.js:33:37:33:44 | "source" | arrays.js:35:8:35:25 | arr4_variant.pop() | | arrays.js:53:4:53:11 | "source" | arrays.js:54:10:54:18 | ary.pop() | +| arrays.js:99:31:99:38 | "source" | arrays.js:100:8:100:17 | arr8.pop() | +| arrays.js:103:55:103:62 | "source" | arrays.js:105:8:105:25 | arr8_variant.pop() | diff --git a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected index 6f62ae76f152..a531715bfb6b 100644 --- a/javascript/ql/test/library-tests/Arrays/TaintFlow.expected +++ b/javascript/ql/test/library-tests/Arrays/TaintFlow.expected @@ -14,6 +14,7 @@ | arrays.js:2:16:2:23 | "source" | arrays.js:86:8:86:35 | arrayFi ... llback) | | arrays.js:2:16:2:23 | "source" | arrays.js:90:10:90:10 | x | | arrays.js:2:16:2:23 | "source" | arrays.js:93:8:93:17 | arr.at(-1) | +| arrays.js:2:16:2:23 | "source" | arrays.js:109:8:109:24 | arr8_spread.pop() | | arrays.js:18:22:18:29 | "source" | arrays.js:18:50:18:50 | e | | arrays.js:22:15:22:22 | "source" | arrays.js:23:8:23:17 | arr2.pop() | | arrays.js:25:15:25:22 | "source" | arrays.js:26:8:26:17 | arr3.pop() | @@ -26,3 +27,5 @@ | arrays.js:53:4:53:11 | "source" | arrays.js:55:10:55:12 | ary | | arrays.js:95:9:95:16 | "source" | arrays.js:95:8:95:34 | ["sourc ... ) => x) | | arrays.js:96:9:96:16 | "source" | arrays.js:96:8:96:36 | ["sourc ... => !!x) | +| arrays.js:99:31:99:38 | "source" | arrays.js:100:8:100:17 | arr8.pop() | +| arrays.js:103:55:103:62 | "source" | arrays.js:105:8:105:25 | arr8_variant.pop() | diff --git a/javascript/ql/test/library-tests/Arrays/arrays.js b/javascript/ql/test/library-tests/Arrays/arrays.js index 9806ec2e395d..579741fa3aac 100644 --- a/javascript/ql/test/library-tests/Arrays/arrays.js +++ b/javascript/ql/test/library-tests/Arrays/arrays.js @@ -94,4 +94,17 @@ sink(["source"].filter((x) => x)); // NOT OK sink(["source"].filter((x) => !!x)); // NOT OK + + var arr8 = []; + arr8 = arr8.toSpliced(0, 0, "source"); + sink(arr8.pop()); // NOT OK + + var arr8_variant = []; + arr8_variant = arr8_variant.toSpliced(0, 0, "safe", "source"); + arr8_variant.pop(); + sink(arr8_variant.pop()); // NOT OK + + var arr8_spread = []; + arr8_spread = arr8_spread.toSpliced(0, 0, ...arr); + sink(arr8_spread.pop()); // NOT OK }); diff --git a/javascript/ql/test/library-tests/Arrays/printAst.expected b/javascript/ql/test/library-tests/Arrays/printAst.expected index 2d0fdb458636..a7333b294853 100644 --- a/javascript/ql/test/library-tests/Arrays/printAst.expected +++ b/javascript/ql/test/library-tests/Arrays/printAst.expected @@ -1,9 +1,9 @@ nodes -| arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | -| arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | +| arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | semmle.label | [ParExpr] (functi ... T OK }) | +| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | semmle.label | [ExprStmt] (functi ... OK }); | +| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | semmle.order | 1 | +| arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | semmle.label | [FunctionExpr] functio ... OT OK } | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | semmle.label | [BlockStmt] { let ... OT OK } | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | [DeclStmt] let source = ... | | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | [VarDecl] source | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | [VariableDeclarator] source = "source" | @@ -417,6 +417,82 @@ nodes | arrays.js:96:33:96:35 | [UnaryExpr] !!x | semmle.label | [UnaryExpr] !!x | | arrays.js:96:34:96:35 | [UnaryExpr] !x | semmle.label | [UnaryExpr] !x | | arrays.js:96:35:96:35 | [VarRef] x | semmle.label | [VarRef] x | +| arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | [DeclStmt] var arr8 = ... | +| arrays.js:98:7:98:10 | [VarDecl] arr8 | semmle.label | [VarDecl] arr8 | +| arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | semmle.label | [VariableDeclarator] arr8 = [] | +| arrays.js:98:14:98:15 | [ArrayExpr] [] | semmle.label | [ArrayExpr] [] | +| arrays.js:99:3:99:6 | [VarRef] arr8 | semmle.label | [VarRef] arr8 | +| arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | semmle.label | [AssignExpr] arr8 = ... ource") | +| arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | [ExprStmt] arr8 = ... urce"); | +| arrays.js:99:10:99:13 | [VarRef] arr8 | semmle.label | [VarRef] arr8 | +| arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | semmle.label | [DotExpr] arr8.toSpliced | +| arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | semmle.label | [MethodCallExpr] arr8.to ... ource") | +| arrays.js:99:15:99:23 | [Label] toSpliced | semmle.label | [Label] toSpliced | +| arrays.js:99:25:99:25 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:99:28:99:28 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:99:31:99:38 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:100:3:100:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | semmle.label | [CallExpr] sink(arr8.pop()) | +| arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | [ExprStmt] sink(arr8.pop()); | +| arrays.js:100:8:100:11 | [VarRef] arr8 | semmle.label | [VarRef] arr8 | +| arrays.js:100:8:100:15 | [DotExpr] arr8.pop | semmle.label | [DotExpr] arr8.pop | +| arrays.js:100:8:100:17 | [MethodCallExpr] arr8.pop() | semmle.label | [MethodCallExpr] arr8.pop() | +| arrays.js:100:13:100:15 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | [DeclStmt] var arr8_variant = ... | +| arrays.js:102:7:102:18 | [VarDecl] arr8_variant | semmle.label | [VarDecl] arr8_variant | +| arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | semmle.label | [VariableDeclarator] arr8_variant = [] | +| arrays.js:102:22:102:23 | [ArrayExpr] [] | semmle.label | [ArrayExpr] [] | +| arrays.js:103:3:103:14 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | semmle.label | [AssignExpr] arr8_va ... ource") | +| arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | [ExprStmt] arr8_va ... urce"); | +| arrays.js:103:18:103:29 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | semmle.label | [DotExpr] arr8_va ... Spliced | +| arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | semmle.label | [MethodCallExpr] arr8_va ... ource") | +| arrays.js:103:31:103:39 | [Label] toSpliced | semmle.label | [Label] toSpliced | +| arrays.js:103:41:103:41 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:103:44:103:44 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:103:47:103:52 | [Literal] "safe" | semmle.label | [Literal] "safe" | +| arrays.js:103:55:103:62 | [Literal] "source" | semmle.label | [Literal] "source" | +| arrays.js:104:3:104:14 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | semmle.label | [DotExpr] arr8_variant.pop | +| arrays.js:104:3:104:20 | [MethodCallExpr] arr8_variant.pop() | semmle.label | [MethodCallExpr] arr8_variant.pop() | +| arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | [ExprStmt] arr8_variant.pop(); | +| arrays.js:104:16:104:18 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:105:3:105:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | semmle.label | [CallExpr] sink(ar ... .pop()) | +| arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | [ExprStmt] sink(ar ... pop()); | +| arrays.js:105:8:105:19 | [VarRef] arr8_variant | semmle.label | [VarRef] arr8_variant | +| arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | semmle.label | [DotExpr] arr8_variant.pop | +| arrays.js:105:8:105:25 | [MethodCallExpr] arr8_variant.pop() | semmle.label | [MethodCallExpr] arr8_variant.pop() | +| arrays.js:105:21:105:23 | [Label] pop | semmle.label | [Label] pop | +| arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | [DeclStmt] var arr8_spread = ... | +| arrays.js:107:7:107:17 | [VarDecl] arr8_spread | semmle.label | [VarDecl] arr8_spread | +| arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | semmle.label | [VariableDeclarator] arr8_spread = [] | +| arrays.js:107:21:107:22 | [ArrayExpr] [] | semmle.label | [ArrayExpr] [] | +| arrays.js:108:3:108:13 | [VarRef] arr8_spread | semmle.label | [VarRef] arr8_spread | +| arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | semmle.label | [AssignExpr] arr8_sp ... ...arr) | +| arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | [ExprStmt] arr8_sp ... ..arr); | +| arrays.js:108:17:108:27 | [VarRef] arr8_spread | semmle.label | [VarRef] arr8_spread | +| arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | semmle.label | [DotExpr] arr8_sp ... Spliced | +| arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | semmle.label | [MethodCallExpr] arr8_sp ... ...arr) | +| arrays.js:108:29:108:37 | [Label] toSpliced | semmle.label | [Label] toSpliced | +| arrays.js:108:39:108:39 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:108:42:108:42 | [Literal] 0 | semmle.label | [Literal] 0 | +| arrays.js:108:45:108:50 | [SpreadElement] ...arr | semmle.label | [SpreadElement] ...arr | +| arrays.js:108:48:108:50 | [VarRef] arr | semmle.label | [VarRef] arr | +| arrays.js:109:3:109:6 | [VarRef] sink | semmle.label | [VarRef] sink | +| arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | semmle.label | [CallExpr] sink(ar ... .pop()) | +| arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | [ExprStmt] sink(ar ... pop()); | +| arrays.js:109:8:109:18 | [VarRef] arr8_spread | semmle.label | [VarRef] arr8_spread | +| arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | semmle.label | [DotExpr] arr8_spread.pop | +| arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | semmle.label | [MethodCallExpr] arr8_spread.pop() | +| arrays.js:109:20:109:22 | [Label] pop | semmle.label | [Label] pop | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | @@ -476,108 +552,128 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | edges -| arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | -| arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | -| arrays.js:1:1:97:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:97:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | -| arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | -| arrays.js:1:2:97:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | -| arrays.js:1:14:97:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | +| arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | semmle.label | 1 | +| arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | semmle.order | 1 | +| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | semmle.label | 1 | +| arrays.js:1:1:110:3 | [ExprStmt] (functi ... OK }); | arrays.js:1:1:110:2 | [ParExpr] (functi ... T OK }) | semmle.order | 1 | +| arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | semmle.label | 5 | +| arrays.js:1:2:110:1 | [FunctionExpr] functio ... OT OK } | arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | semmle.order | 5 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.label | 1 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | semmle.order | 1 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.label | 2 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:4:3:4:28 | [DeclStmt] var obj = ... | semmle.order | 2 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.label | 3 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:5:3:5:16 | [ExprStmt] sink(obj.foo); | semmle.order | 3 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.label | 4 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:7:3:7:15 | [DeclStmt] var arr = ... | semmle.order | 4 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.label | 5 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:8:3:8:19 | [ExprStmt] arr.push(source); | semmle.order | 5 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.label | 6 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:10:3:12:3 | [ForStmt] for (va ... OK } | semmle.order | 6 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.label | 7 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:15:3:15:30 | [ExprStmt] arr.for ... nk(e)); | semmle.order | 7 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.label | 8 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:16:3:16:26 | [ExprStmt] arr.map ... nk(e)); | semmle.order | 8 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.label | 9 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:18:3:18:53 | [ExprStmt] [1, 2, ... nk(e)); | semmle.order | 9 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.label | 10 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:20:3:20:18 | [ExprStmt] sink(arr.pop()); | semmle.order | 10 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.label | 11 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:22:3:22:24 | [DeclStmt] var arr2 = ... | semmle.order | 11 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.label | 12 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:23:3:23:19 | [ExprStmt] sink(arr2.pop()); | semmle.order | 12 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.label | 13 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:25:3:25:24 | [DeclStmt] var arr3 = ... | semmle.order | 13 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.label | 14 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:26:3:26:19 | [ExprStmt] sink(arr3.pop()); | semmle.order | 14 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.label | 15 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:28:3:28:16 | [DeclStmt] var arr4 = ... | semmle.order | 15 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.label | 16 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:29:3:29:30 | [ExprStmt] arr4.sp ... urce"); | semmle.order | 16 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.label | 17 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:30:3:30:19 | [ExprStmt] sink(arr4.pop()); | semmle.order | 17 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.label | 18 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:32:3:32:24 | [DeclStmt] var arr4_variant = ... | semmle.order | 18 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.label | 19 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:33:3:33:46 | [ExprStmt] arr4_va ... urce"); | semmle.order | 19 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.label | 20 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:34:3:34:21 | [ExprStmt] arr4_variant.pop(); | semmle.order | 20 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 21 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:35:3:35:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 21 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.label | 22 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:37:3:37:23 | [DeclStmt] var arr4_spread = ... | semmle.order | 22 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.label | 23 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:38:3:38:35 | [ExprStmt] arr4_sp ... ..arr); | semmle.order | 23 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 24 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:39:3:39:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 24 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.label | 25 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:41:3:41:29 | [DeclStmt] var arr5 = ... | semmle.order | 25 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.label | 26 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:42:3:42:19 | [ExprStmt] sink(arr5.pop()); | semmle.order | 26 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.label | 27 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:44:3:44:28 | [ExprStmt] sink(ar ... pop()); | semmle.order | 27 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.label | 28 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:46:3:46:16 | [DeclStmt] var arr6 = ... | semmle.order | 28 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.label | 29 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:47:3:49:3 | [ForStmt] for (va ... i]; } | semmle.order | 29 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.label | 30 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:50:3:50:19 | [ExprStmt] sink(arr6.pop()); | semmle.order | 30 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.label | 31 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:53:3:56:5 | [ExprStmt] ["sourc ... . }); | semmle.order | 31 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.label | 32 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:58:3:58:15 | [ExprStmt] sink(arr[0]); | semmle.order | 32 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.label | 33 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:60:3:62:3 | [ForOfStmt] for (co ... OK } | semmle.order | 33 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.label | 34 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:64:3:66:3 | [ForOfStmt] for (co ... OK } | semmle.order | 34 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.label | 35 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:68:3:70:3 | [ForOfStmt] for (co ... OK } | semmle.order | 35 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.label | 36 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:72:3:72:16 | [DeclStmt] var arr7 = ... | semmle.order | 36 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.label | 37 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:73:3:73:20 | [ExprStmt] arr7.push(...arr); | semmle.order | 37 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.label | 38 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:74:3:76:3 | [ForOfStmt] for (co ... OK } | semmle.order | 38 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.label | 39 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:78:3:78:42 | [DeclStmt] const arrayFrom = ... | semmle.order | 39 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.label | 40 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:79:3:81:3 | [ForOfStmt] for (co ... OK } | semmle.order | 40 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.label | 41 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:83:3:83:31 | [ExprStmt] sink(ar ... back)); | semmle.order | 41 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.label | 42 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:85:3:85:42 | [DeclStmt] const arrayFind = ... | semmle.order | 42 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.label | 43 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:86:3:86:37 | [ExprStmt] sink(ar ... back)); | semmle.order | 43 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.label | 44 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:88:3:88:31 | [DeclStmt] const uniq = ... | semmle.order | 44 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.label | 45 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:89:3:91:3 | [ForOfStmt] for (co ... OK } | semmle.order | 45 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.label | 46 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:93:3:93:19 | [ExprStmt] sink(arr.at(-1)); | semmle.order | 46 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.label | 47 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:95:3:95:36 | [ExprStmt] sink([" ... => x)); | semmle.order | 47 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.label | 48 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:96:3:96:38 | [ExprStmt] sink([" ... !!x)); | semmle.order | 48 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.label | 49 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | semmle.order | 49 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.label | 50 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | semmle.order | 50 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.label | 51 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | semmle.order | 51 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.label | 52 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | semmle.order | 52 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.label | 53 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | semmle.order | 53 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.label | 54 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | semmle.order | 54 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.label | 55 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | semmle.order | 55 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.label | 56 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | semmle.order | 56 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.label | 57 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | semmle.order | 57 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.label | 58 | +| arrays.js:1:14:110:1 | [BlockStmt] { let ... OT OK } | arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | semmle.order | 58 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.label | 1 | | arrays.js:2:3:2:24 | [DeclStmt] let source = ... | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | semmle.order | 1 | | arrays.js:2:7:2:23 | [VariableDeclarator] source = "source" | arrays.js:2:7:2:12 | [VarDecl] source | semmle.label | 1 | @@ -1288,6 +1384,112 @@ edges | arrays.js:96:33:96:35 | [UnaryExpr] !!x | arrays.js:96:34:96:35 | [UnaryExpr] !x | semmle.order | 1 | | arrays.js:96:34:96:35 | [UnaryExpr] !x | arrays.js:96:35:96:35 | [VarRef] x | semmle.label | 1 | | arrays.js:96:34:96:35 | [UnaryExpr] !x | arrays.js:96:35:96:35 | [VarRef] x | semmle.order | 1 | +| arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | semmle.label | 1 | +| arrays.js:98:3:98:16 | [DeclStmt] var arr8 = ... | arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | semmle.order | 1 | +| arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | arrays.js:98:7:98:10 | [VarDecl] arr8 | semmle.label | 1 | +| arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | arrays.js:98:7:98:10 | [VarDecl] arr8 | semmle.order | 1 | +| arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | arrays.js:98:14:98:15 | [ArrayExpr] [] | semmle.label | 2 | +| arrays.js:98:7:98:15 | [VariableDeclarator] arr8 = [] | arrays.js:98:14:98:15 | [ArrayExpr] [] | semmle.order | 2 | +| arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | arrays.js:99:3:99:6 | [VarRef] arr8 | semmle.label | 1 | +| arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | arrays.js:99:3:99:6 | [VarRef] arr8 | semmle.order | 1 | +| arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | semmle.label | 2 | +| arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | semmle.order | 2 | +| arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | semmle.label | 1 | +| arrays.js:99:3:99:40 | [ExprStmt] arr8 = ... urce"); | arrays.js:99:3:99:39 | [AssignExpr] arr8 = ... ource") | semmle.order | 1 | +| arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | arrays.js:99:10:99:13 | [VarRef] arr8 | semmle.label | 1 | +| arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | arrays.js:99:10:99:13 | [VarRef] arr8 | semmle.order | 1 | +| arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | arrays.js:99:15:99:23 | [Label] toSpliced | semmle.label | 2 | +| arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | arrays.js:99:15:99:23 | [Label] toSpliced | semmle.order | 2 | +| arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | semmle.label | 0 | +| arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | arrays.js:99:10:99:23 | [DotExpr] arr8.toSpliced | semmle.order | 0 | +| arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:99:10:99:39 | [MethodCallExpr] arr8.to ... ource") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | arrays.js:100:3:100:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | arrays.js:100:3:100:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | semmle.label | 1 | +| arrays.js:100:3:100:19 | [ExprStmt] sink(arr8.pop()); | arrays.js:100:3:100:18 | [CallExpr] sink(arr8.pop()) | semmle.order | 1 | +| arrays.js:100:8:100:15 | [DotExpr] arr8.pop | arrays.js:100:8:100:11 | [VarRef] arr8 | semmle.label | 1 | +| arrays.js:100:8:100:15 | [DotExpr] arr8.pop | arrays.js:100:8:100:11 | [VarRef] arr8 | semmle.order | 1 | +| arrays.js:100:8:100:15 | [DotExpr] arr8.pop | arrays.js:100:13:100:15 | [Label] pop | semmle.label | 2 | +| arrays.js:100:8:100:15 | [DotExpr] arr8.pop | arrays.js:100:13:100:15 | [Label] pop | semmle.order | 2 | +| arrays.js:100:8:100:17 | [MethodCallExpr] arr8.pop() | arrays.js:100:8:100:15 | [DotExpr] arr8.pop | semmle.label | 0 | +| arrays.js:100:8:100:17 | [MethodCallExpr] arr8.pop() | arrays.js:100:8:100:15 | [DotExpr] arr8.pop | semmle.order | 0 | +| arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | semmle.label | 1 | +| arrays.js:102:3:102:24 | [DeclStmt] var arr8_variant = ... | arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | semmle.order | 1 | +| arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:102:7:102:18 | [VarDecl] arr8_variant | semmle.label | 1 | +| arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:102:7:102:18 | [VarDecl] arr8_variant | semmle.order | 1 | +| arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:102:22:102:23 | [ArrayExpr] [] | semmle.label | 2 | +| arrays.js:102:7:102:23 | [VariableDeclarator] arr8_variant = [] | arrays.js:102:22:102:23 | [ArrayExpr] [] | semmle.order | 2 | +| arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | arrays.js:103:3:103:14 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | arrays.js:103:3:103:14 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | semmle.label | 2 | +| arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | semmle.order | 2 | +| arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | semmle.label | 1 | +| arrays.js:103:3:103:64 | [ExprStmt] arr8_va ... urce"); | arrays.js:103:3:103:63 | [AssignExpr] arr8_va ... ource") | semmle.order | 1 | +| arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | arrays.js:103:18:103:29 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | arrays.js:103:18:103:29 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | arrays.js:103:31:103:39 | [Label] toSpliced | semmle.label | 2 | +| arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | arrays.js:103:31:103:39 | [Label] toSpliced | semmle.order | 2 | +| arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | semmle.label | 0 | +| arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | arrays.js:103:18:103:39 | [DotExpr] arr8_va ... Spliced | semmle.order | 0 | +| arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:103:18:103:63 | [MethodCallExpr] arr8_va ... ource") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | arrays.js:104:3:104:14 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | arrays.js:104:3:104:14 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | arrays.js:104:16:104:18 | [Label] pop | semmle.label | 2 | +| arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | arrays.js:104:16:104:18 | [Label] pop | semmle.order | 2 | +| arrays.js:104:3:104:20 | [MethodCallExpr] arr8_variant.pop() | arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | semmle.label | 0 | +| arrays.js:104:3:104:20 | [MethodCallExpr] arr8_variant.pop() | arrays.js:104:3:104:18 | [DotExpr] arr8_variant.pop | semmle.order | 0 | +| arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | arrays.js:104:3:104:20 | [MethodCallExpr] arr8_variant.pop() | semmle.label | 1 | +| arrays.js:104:3:104:21 | [ExprStmt] arr8_variant.pop(); | arrays.js:104:3:104:20 | [MethodCallExpr] arr8_variant.pop() | semmle.order | 1 | +| arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | arrays.js:105:3:105:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | arrays.js:105:3:105:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | semmle.label | 1 | +| arrays.js:105:3:105:27 | [ExprStmt] sink(ar ... pop()); | arrays.js:105:3:105:26 | [CallExpr] sink(ar ... .pop()) | semmle.order | 1 | +| arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | arrays.js:105:8:105:19 | [VarRef] arr8_variant | semmle.label | 1 | +| arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | arrays.js:105:8:105:19 | [VarRef] arr8_variant | semmle.order | 1 | +| arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | arrays.js:105:21:105:23 | [Label] pop | semmle.label | 2 | +| arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | arrays.js:105:21:105:23 | [Label] pop | semmle.order | 2 | +| arrays.js:105:8:105:25 | [MethodCallExpr] arr8_variant.pop() | arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | semmle.label | 0 | +| arrays.js:105:8:105:25 | [MethodCallExpr] arr8_variant.pop() | arrays.js:105:8:105:23 | [DotExpr] arr8_variant.pop | semmle.order | 0 | +| arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | semmle.label | 1 | +| arrays.js:107:3:107:23 | [DeclStmt] var arr8_spread = ... | arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | semmle.order | 1 | +| arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:107:7:107:17 | [VarDecl] arr8_spread | semmle.label | 1 | +| arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:107:7:107:17 | [VarDecl] arr8_spread | semmle.order | 1 | +| arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:107:21:107:22 | [ArrayExpr] [] | semmle.label | 2 | +| arrays.js:107:7:107:22 | [VariableDeclarator] arr8_spread = [] | arrays.js:107:21:107:22 | [ArrayExpr] [] | semmle.order | 2 | +| arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:108:3:108:13 | [VarRef] arr8_spread | semmle.label | 1 | +| arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:108:3:108:13 | [VarRef] arr8_spread | semmle.order | 1 | +| arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | semmle.label | 2 | +| arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | semmle.order | 2 | +| arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | semmle.label | 1 | +| arrays.js:108:3:108:52 | [ExprStmt] arr8_sp ... ..arr); | arrays.js:108:3:108:51 | [AssignExpr] arr8_sp ... ...arr) | semmle.order | 1 | +| arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:108:17:108:27 | [VarRef] arr8_spread | semmle.label | 1 | +| arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:108:17:108:27 | [VarRef] arr8_spread | semmle.order | 1 | +| arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:108:29:108:37 | [Label] toSpliced | semmle.label | 2 | +| arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | arrays.js:108:29:108:37 | [Label] toSpliced | semmle.order | 2 | +| arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | semmle.label | 0 | +| arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | arrays.js:108:17:108:37 | [DotExpr] arr8_sp ... Spliced | semmle.order | 0 | +| arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:108:17:108:51 | [MethodCallExpr] arr8_sp ... ...arr) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:108:45:108:50 | [SpreadElement] ...arr | arrays.js:108:48:108:50 | [VarRef] arr | semmle.label | 1 | +| arrays.js:108:45:108:50 | [SpreadElement] ...arr | arrays.js:108:48:108:50 | [VarRef] arr | semmle.order | 1 | +| arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | arrays.js:109:3:109:6 | [VarRef] sink | semmle.label | 0 | +| arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | arrays.js:109:3:109:6 | [VarRef] sink | semmle.order | 0 | +| arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | semmle.label | 1 | +| arrays.js:109:3:109:26 | [ExprStmt] sink(ar ... pop()); | arrays.js:109:3:109:25 | [CallExpr] sink(ar ... .pop()) | semmle.order | 1 | +| arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | arrays.js:109:8:109:18 | [VarRef] arr8_spread | semmle.label | 1 | +| arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | arrays.js:109:8:109:18 | [VarRef] arr8_spread | semmle.order | 1 | +| arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | arrays.js:109:20:109:22 | [Label] pop | semmle.label | 2 | +| arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | arrays.js:109:20:109:22 | [Label] pop | semmle.order | 2 | +| arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | semmle.label | 0 | +| arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | arrays.js:109:8:109:22 | [DotExpr] arr8_spread.pop | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:5:8:5:14 | [DotExpr] obj.foo | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:8:12:8:17 | [VarRef] source | semmle.label | 0 | @@ -1406,6 +1608,32 @@ edges | file://:0:0:0:0 | (Arguments) | arrays.js:96:8:96:36 | [MethodCallExpr] ["sourc ... => !!x) | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | arrays.js:96:26:96:35 | [ArrowFunctionExpr] (x) => !!x | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:99:25:99:25 | [Literal] 0 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:99:25:99:25 | [Literal] 0 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:99:28:99:28 | [Literal] 0 | semmle.label | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:99:28:99:28 | [Literal] 0 | semmle.order | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:99:31:99:38 | [Literal] "source" | semmle.label | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:99:31:99:38 | [Literal] "source" | semmle.order | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:8:100:17 | [MethodCallExpr] arr8.pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:100:8:100:17 | [MethodCallExpr] arr8.pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:41:103:41 | [Literal] 0 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:41:103:41 | [Literal] 0 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:44:103:44 | [Literal] 0 | semmle.label | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:44:103:44 | [Literal] 0 | semmle.order | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:47:103:52 | [Literal] "safe" | semmle.label | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:47:103:52 | [Literal] "safe" | semmle.order | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:55:103:62 | [Literal] "source" | semmle.label | 3 | +| file://:0:0:0:0 | (Arguments) | arrays.js:103:55:103:62 | [Literal] "source" | semmle.order | 3 | +| file://:0:0:0:0 | (Arguments) | arrays.js:105:8:105:25 | [MethodCallExpr] arr8_variant.pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:105:8:105:25 | [MethodCallExpr] arr8_variant.pop() | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:108:39:108:39 | [Literal] 0 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:108:39:108:39 | [Literal] 0 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:108:42:108:42 | [Literal] 0 | semmle.label | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:108:42:108:42 | [Literal] 0 | semmle.order | 1 | +| file://:0:0:0:0 | (Arguments) | arrays.js:108:45:108:50 | [SpreadElement] ...arr | semmle.label | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:108:45:108:50 | [SpreadElement] ...arr | semmle.order | 2 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | arrays.js:109:8:109:24 | [MethodCallExpr] arr8_spread.pop() | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:15:16:15:16 | [SimpleParameter] e | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | arrays.js:16:12:16:12 | [SimpleParameter] e | semmle.label | 0 | diff --git a/javascript/ql/test/library-tests/RegExp/IsRegex/IsRegex.expected b/javascript/ql/test/library-tests/RegExp/IsRegex/IsRegex.expected new file mode 100644 index 000000000000..0fb07c050d46 --- /dev/null +++ b/javascript/ql/test/library-tests/RegExp/IsRegex/IsRegex.expected @@ -0,0 +1,3 @@ +| tst.js:1:12:1:38 | '^http: ... le.com' | is a regular expression | +| tst.js:4:37:4:43 | 'regex' | is a regular expression | +| tst.js:9:37:9:43 | 'regex' | is a regular expression | diff --git a/javascript/ql/test/library-tests/RegExp/IsRegex/IsRegex.ql b/javascript/ql/test/library-tests/RegExp/IsRegex/IsRegex.ql new file mode 100644 index 000000000000..0e57c8226604 --- /dev/null +++ b/javascript/ql/test/library-tests/RegExp/IsRegex/IsRegex.ql @@ -0,0 +1,4 @@ +import javascript + +from RegExpPatternSource regex +select regex, "is a regular expression" diff --git a/javascript/ql/test/library-tests/RegExp/IsRegex/tst.js b/javascript/ql/test/library-tests/RegExp/IsRegex/tst.js new file mode 100644 index 000000000000..3776821f7851 --- /dev/null +++ b/javascript/ql/test/library-tests/RegExp/IsRegex/tst.js @@ -0,0 +1,11 @@ +new RegExp('^http://test\.example.com'); // NOT OK + +function detectRegexViaSplice(string) { + let found = getMyThing().search('regex'); // NOT OK + arr.splice(found, 1); +}; + +function detectRegexViaToSpliced(string) { + let found = getMyThing().search('regex'); // NOT OK + arr.toSpliced(found, 1); +}; diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index ba15575eb9cd..884657842058 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -23,6 +23,11 @@ typeInferenceMismatch | array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h | | array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i | | array-mutation.js:39:17:39:24 | source() | array-mutation.js:40:8:40:8 | j | +| array-mutation.js:43:36:43:43 | source() | array-mutation.js:45:8:45:15 | kSpliced | +| array-mutation.js:48:25:48:32 | source() | array-mutation.js:49:8:49:8 | l | +| array-mutation.js:68:21:68:28 | source() | array-mutation.js:69:8:69:8 | q | +| array-mutation.js:72:39:72:46 | source() | array-mutation.js:73:8:73:15 | rSpliced | +| array-mutation.js:75:28:75:35 | source() | array-mutation.js:76:8:76:8 | r | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] | @@ -234,10 +239,11 @@ typeInferenceMismatch | tst.js:2:13:2:20 | source() | tst.js:51:10:51:31 | seriali ... ript(x) | | tst.js:2:13:2:20 | source() | tst.js:54:14:54:19 | unsafe | | tst.js:2:13:2:20 | source() | tst.js:61:10:61:20 | x.reverse() | -| tst.js:2:13:2:20 | source() | tst.js:63:10:63:21 | x.toSorted() | -| tst.js:2:13:2:20 | source() | tst.js:65:10:65:16 | xSorted | -| tst.js:2:13:2:20 | source() | tst.js:67:10:67:23 | x.toReversed() | -| tst.js:2:13:2:20 | source() | tst.js:69:10:69:18 | xReversed | +| tst.js:2:13:2:20 | source() | tst.js:62:10:62:22 | x.toSpliced() | +| tst.js:2:13:2:20 | source() | tst.js:64:10:64:21 | x.toSorted() | +| tst.js:2:13:2:20 | source() | tst.js:66:10:66:16 | xSorted | +| tst.js:2:13:2:20 | source() | tst.js:68:10:68:23 | x.toReversed() | +| tst.js:2:13:2:20 | source() | tst.js:70:10:70:18 | xReversed | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | | xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result | | xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr | diff --git a/javascript/ql/test/library-tests/TaintTracking/array-mutation.js b/javascript/ql/test/library-tests/TaintTracking/array-mutation.js index cc581d34a253..072355368456 100644 --- a/javascript/ql/test/library-tests/TaintTracking/array-mutation.js +++ b/javascript/ql/test/library-tests/TaintTracking/array-mutation.js @@ -38,4 +38,40 @@ function test(x, y) { let j = []; j[j.length] = source(); sink(j); // NOT OK + + let k = []; + let kSpliced = k.toSpliced(x, y, source()); + sink(k); // OK + sink(kSpliced); // NOT OK + + let l = []; + l = l.toSpliced(x, y, source()); + sink(l); // NOT OK + + let m = []; + m = m.toSpliced(q, source(), y); + sink(m); // OK + + let n = []; + n = n.toSpliced(source(), x); + sink(n); // OK + + let o = []; + o = o.toSpliced(x, source()); + sink(o); // OK + + let p = []; + p = p.toSpliced(source(), x, y); + sink(p); // OK + + let q = []; + q.splice(x, y, ...source()); + sink(q); // NOT OK + + let r = []; + let rSpliced = r.toSpliced(x, y, ...source()); + sink(rSpliced); // NOT OK + sink(r); // OK + r = r.toSpliced(x, y, ...source()); + sink(r); // NOT OK } diff --git a/javascript/ql/test/library-tests/TaintTracking/tst.js b/javascript/ql/test/library-tests/TaintTracking/tst.js index 3af935687a06..a5142e29685f 100644 --- a/javascript/ql/test/library-tests/TaintTracking/tst.js +++ b/javascript/ql/test/library-tests/TaintTracking/tst.js @@ -59,6 +59,7 @@ function test() { tagged`foo ${"safe"} bar ${x} baz`; sink(x.reverse()); // NOT OK + sink(x.toSpliced()); // NOT OK sink(x.toSorted()) // NOT OK const xSorted = x.toSorted();