Merge branch 'main' into js/shared-dataflow-merge-main

This commit is contained in:
Asger F
2024-12-19 10:14:38 +01:00
3417 changed files with 72118 additions and 42902 deletions

View File

@@ -1,7 +1,10 @@
import javascript
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" }
predicate isSource(DataFlow::Node source) {
source.asExpr().getStringValue() = "source" or
source.(DataFlow::CallNode).getCalleeName() = "source"
}
predicate isSink(DataFlow::Node sink) {
sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument()

View File

@@ -1,7 +1,10 @@
import javascript
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" }
predicate isSource(DataFlow::Node source) {
source.asExpr().getStringValue() = "source" or
source.(DataFlow::CallNode).getCalleeName() = "source"
}
predicate isSink(DataFlow::Node sink) {
sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument()

View File

@@ -108,4 +108,41 @@
var arr8_spread = [];
arr8_spread = arr8_spread.toSpliced(0, 0, ...arr);
sink(arr8_spread.pop()); // NOT OK
sink(arr.findLast(someCallback)); // NOT OK
{ // Test for findLast function
const list = ["source"];
const element = list.findLast((item) => sink(item)); // NOT OK
sink(element); // NOT OK
}
{ // Test for find function
const list = ["source"];
const element = list.find((item) => sink(item)); // NOT OK
sink(element); // NOT OK
}
{ // Test for findLastIndex function
const list = ["source"];
const element = list.findLastIndex((item) => sink(item)); // NOT OK
sink(element); // OK
}
{
const arr = source();
const element1 = arr.find((item) => sink(item)); // NOT OK
sink(element1); // NOT OK
}
{
const arr = source();
const element1 = arr.findLast((item) => sink(item)); // NOT OK
sink(element1); // NOT OK
}
{
const arr = source();
const element1 = arr.findLastIndex((item) => sink(item)); // NOT OK
sink(element1); // OK
}
});

View File

@@ -5,4 +5,3 @@ ambiguousPreferredPredecessor
| pack2/main.js:1:1:3:1 | def moduleImport("pack2").getMember("exports").getMember("MainClass").getInstance() |
ambiguousSinkName
ambiguousFunctionName
failures

View File

@@ -2,7 +2,7 @@ import javascript
import semmle.javascript.RestrictedLocations
import semmle.javascript.Lines
import semmle.javascript.endpoints.EndpointNaming as EndpointNaming
import testUtilities.InlineExpectationsTest
import utils.test.InlineExpectationsTest
import EndpointNaming::Debug
private predicate isIgnored(DataFlow::FunctionNode function) {

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" }

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
API::Node testInstance() { result = API::moduleImport("@example/test").getInstance() }

View File

@@ -1,6 +1,6 @@
import javascript
private import semmle.javascript.heuristics.AdditionalSources
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof HeuristicSource }

View File

@@ -0,0 +1,12 @@
function test() {
let x = source();
sink(x.toWellFormed()); // NOT OK
const wellFormedX = x.toWellFormed();
sink(wellFormedX); // NOT OK
const concatWellFormedX = "/" + wellFormedX + "!";
sink(concatWellFormedX); // NOT OK
sink(source().toWellFormed()); // NOT OK
}

View File

@@ -69,6 +69,34 @@ function test() {
const xReversed = x.toReversed();
sink(xReversed) // NOT OK
sink(Map.groupBy(x, z => z)); // NOT OK
sink(Custom.groupBy(x, z => z)); // OK
sink(Object.groupBy(x, z => z)); // NOT OK
sink(Map.groupBy(source(), (item) => sink(item))); // NOT OK
{
const grouped = Map.groupBy(x, (item) => sink(item)); // NOT OK
sink(grouped); // NOT OK
}
{
const list = [source()];
const grouped = Map.groupBy(list, (item) => sink(item)); // NOT OK
sink(grouped); // NOT OK
}
{
const data = source();
const result = Object.groupBy(data, item => item);
const taintedValue = result[notDefined()];
sink(taintedValue); // NOT OK
}
{
const data = source();
const map = Map.groupBy(data, item => item);
const taintedValue = map.get(true);
sink(taintedValue); // NOT OK
sink(map.get(true)); // NOT OK
}
sink(x.with()) // NOT OK
const xWith = x.with();
sink(xWith) // NOT OK

View File

@@ -1877,8 +1877,35 @@ nodes
| tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | semmle.label | [MethodCallExpr] obj[key ... rCase() |
| tst.ts:508:21:508:23 | [VarRef] key | semmle.label | [VarRef] key |
| tst.ts:508:26:508:36 | [Label] toUpperCase | semmle.label | [Label] toUpperCase |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | semmle.label | [NamespaceDeclaration] namespa ... type. } |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | semmle.order | 92 |
| tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.label | [VarDecl] TS57 |
| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.label | [DeclStmt] const a = ... |
| tst.ts:514:17:514:17 | [VarDecl] a | semmle.label | [VarDecl] a |
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.label | [VariableDeclarator] a: symbol |
| tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.label | [KeywordTypeExpr] symbol |
| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.label | [ExportDeclaration] export ... }; } |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.label | [ClassDefinition,TypeDefinition] class A ... }; } |
| tst.ts:515:16:515:16 | [VarDecl] A | semmle.label | [VarDecl] A |
| tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
| tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
| tst.ts:515:18:515:17 | [Label] constructor | semmle.label | [Label] constructor |
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.label | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } |
| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.label | [FunctionExpr] [a]() { return 1 } |
| tst.ts:516:8:516:8 | [VarRef] a | semmle.label | [VarRef] a |
| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.label | [BlockStmt] { return 1 } |
| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.label | [ReturnStmt] return 1 |
| tst.ts:516:22:516:22 | [Literal] 1 | semmle.label | [Literal] 1 |
| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.label | [DeclStmt] const e1 = ... |
| tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.label | [VarDecl] e1 |
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.label | [VariableDeclarator] e1: A[typeof a] |
| tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.label | [LocalTypeAccess] A |
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.label | [IndexedAccessTypeExpr] A[typeof a] |
| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.label | [TypeofTypeExpr] typeof a |
| tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.label | [LocalVarTypeAccess] a |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 92 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 93 |
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
| tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | [VarDecl] tstModuleCJS |
| tstModuleCJS.cts:1:33:1:35 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
@@ -1896,7 +1923,7 @@ nodes
| tstModuleCJS.cts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
| tstModuleCJS.cts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 93 |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 94 |
| tstModuleES.mts:1:16:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
| tstModuleES.mts:1:25:1:35 | [VarDecl] tstModuleES | semmle.label | [VarDecl] tstModuleES |
| tstModuleES.mts:1:40:1:42 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
@@ -1914,7 +1941,7 @@ nodes
| tstModuleES.mts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
| tstModuleES.mts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 94 |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 95 |
| tstSuffixA.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixA.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixA.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixA.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixA.ts' |
@@ -1922,7 +1949,7 @@ nodes
| tstSuffixA.ts:2:5:2:27 | [ReturnStmt] return ... xA.ts'; | semmle.label | [ReturnStmt] return ... xA.ts'; |
| tstSuffixA.ts:2:12:2:26 | [Literal] 'tstSuffixA.ts' | semmle.label | [Literal] 'tstSuffixA.ts' |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 95 |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 96 |
| tstSuffixB.ios.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixB.ios.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixB.ios.ts:1:33:1:51 | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ios.ts' |
@@ -1930,7 +1957,7 @@ nodes
| tstSuffixB.ios.ts:2:5:2:31 | [ReturnStmt] return ... os.ts'; | semmle.label | [ReturnStmt] return ... os.ts'; |
| tstSuffixB.ios.ts:2:12:2:30 | [Literal] 'tstSuffixB.ios.ts' | semmle.label | [Literal] 'tstSuffixB.ios.ts' |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 96 |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 97 |
| tstSuffixB.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixB.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixB.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixB.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ts' |
@@ -1938,16 +1965,16 @@ nodes
| tstSuffixB.ts:2:5:2:27 | [ReturnStmt] return ... xB.ts'; | semmle.label | [ReturnStmt] return ... xB.ts'; |
| tstSuffixB.ts:2:12:2:26 | [Literal] 'tstSuffixB.ts' | semmle.label | [Literal] 'tstSuffixB.ts' |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 97 |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 98 |
| type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B |
| type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 98 |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 99 |
| type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b |
| type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B |
| type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 99 |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 100 |
| type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray |
| type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T |
| type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T |
@@ -1959,14 +1986,14 @@ nodes
| type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray<T> | semmle.label | [GenericTypeExpr] ValueOrArray<T> |
| type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 100 |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 101 |
| type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c |
| type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> |
| type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray |
| type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray<number> | semmle.label | [GenericTypeExpr] ValueOrArray<number> |
| type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 101 |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 102 |
| type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json |
| type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] |
| type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -1982,12 +2009,12 @@ nodes
| type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
| type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 102 |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 103 |
| type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json |
| type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json |
| type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 103 |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 104 |
| type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode |
| type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] |
| type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -2003,7 +2030,7 @@ nodes
| type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
| type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 104 |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 105 |
| type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode |
| type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] |
| type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
@@ -2028,12 +2055,12 @@ nodes
| type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" |
| type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 105 |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 106 |
| type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 106 |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 107 |
| type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} |
| type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C |
| type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
@@ -2041,36 +2068,36 @@ nodes
| type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
| type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 107 |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 108 |
| type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj |
| type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C |
| type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 108 |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 109 |
| type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} |
| type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 109 |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 110 |
| type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj |
| type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E |
| type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 110 |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 111 |
| type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} |
| type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N |
| type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 111 |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 112 |
| type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj |
| type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N |
| type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 112 |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 113 |
| type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 113 |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 114 |
| type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I |
| type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S |
| type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S |
@@ -2078,14 +2105,14 @@ nodes
| type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; |
| type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 114 |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 115 |
| type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i |
| type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I<number> | semmle.label | [VariableDeclarator] i: I<number> |
| type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I |
| type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I<number> | semmle.label | [GenericTypeExpr] I<number> |
| type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 115 |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 116 |
| type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C |
| type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
| type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
@@ -2097,14 +2124,14 @@ nodes
| type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T |
| type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 116 |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 117 |
| type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c |
| type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C<number> | semmle.label | [VariableDeclarator] c: C<number> |
| type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C |
| type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C<number> | semmle.label | [GenericTypeExpr] C<number> |
| type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 117 |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 118 |
| type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color |
| type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red |
| type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red |
@@ -2113,29 +2140,29 @@ nodes
| type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue |
| type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 118 |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 119 |
| type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color |
| type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color |
| type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 119 |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 120 |
| type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember |
| type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member |
| type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 120 |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 121 |
| type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e |
| type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember |
| type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 121 |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 122 |
| type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias |
| type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T |
| type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T |
| type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 122 |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 123 |
| type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray |
| type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> |
| type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias |
@@ -5534,6 +5561,56 @@ edges
| tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | tst.ts:508:26:508:36 | [Label] toUpperCase | semmle.order | 2 |
| tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | semmle.label | 0 |
| tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | semmle.order | 0 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.label | 1 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.order | 1 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.label | 2 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.order | 2 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.label | 3 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.order | 3 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.label | 4 |
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.order | 4 |
| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.label | 1 |
| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.order | 1 |
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:17:514:17 | [VarDecl] a | semmle.label | 1 |
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:17:514:17 | [VarDecl] a | semmle.order | 1 |
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.label | 2 |
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.order | 2 |
| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.label | 1 |
| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.order | 1 |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:16:515:16 | [VarDecl] A | semmle.label | 1 |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:16:515:16 | [VarDecl] A | semmle.order | 1 |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.label | 3 |
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.order | 3 |
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.label | 2 |
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.order | 2 |
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [Label] constructor | semmle.label | 1 |
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [Label] constructor | semmle.order | 1 |
| tst.ts:515:18:515:17 | [FunctionExpr] () {} | tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.label | 5 |
| tst.ts:515:18:515:17 | [FunctionExpr] () {} | tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.order | 5 |
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.label | 1 |
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.order | 1 |
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:8:516:8 | [VarRef] a | semmle.label | 2 |
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:8:516:8 | [VarRef] a | semmle.order | 2 |
| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.label | 5 |
| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.order | 5 |
| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.label | 1 |
| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.order | 1 |
| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | tst.ts:516:22:516:22 | [Literal] 1 | semmle.label | 1 |
| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | tst.ts:516:22:516:22 | [Literal] 1 | semmle.order | 1 |
| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.label | 1 |
| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.order | 1 |
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.label | 1 |
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.order | 1 |
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.label | 2 |
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.order | 2 |
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.label | 1 |
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.order | 1 |
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.label | 2 |
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.order | 2 |
| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.label | 1 |
| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.order | 1 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | 1 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.order | 1 |
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | 0 |

View File

@@ -728,6 +728,13 @@ getExprType
| tst.ts:508:17:508:38 | obj[key ... rCase() | string |
| tst.ts:508:21:508:23 | key | string |
| tst.ts:508:26:508:36 | toUpperCase | () => string |
| tst.ts:513:11:513:14 | TS57 | typeof TS57 in tst.ts |
| tst.ts:514:17:514:17 | a | symbol |
| tst.ts:515:16:515:16 | A | A |
| tst.ts:516:7:516:24 | [a]() { return 1 } | () => number |
| tst.ts:516:8:516:8 | a | symbol |
| tst.ts:516:22:516:22 | 1 | 1 |
| tst.ts:519:17:519:18 | e1 | () => number |
| tstModuleCJS.cts:1:17:1:28 | tstModuleCJS | () => "a" \| "b" |
| tstModuleCJS.cts:2:12:2:15 | Math | Math |
| tstModuleCJS.cts:2:12:2:22 | Math.random | () => number |
@@ -843,6 +850,7 @@ getTypeDefinitionType
| tst.ts:447:5:458:5 | class P ... }\\n } | Person |
| tst.ts:473:5:476:5 | class S ... ;\\n } | SomeClass |
| tst.ts:481:5:481:34 | type Pa ... T, T]; | Pair3<T> |
| tst.ts:515:10:517:3 | class A ... };\\n } | A |
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
@@ -1219,6 +1227,11 @@ getTypeExprType
| tst.ts:506:27:506:32 | string | string |
| tst.ts:506:35:506:41 | unknown | unknown |
| tst.ts:506:50:506:55 | string | string |
| tst.ts:514:20:514:25 | symbol | symbol |
| tst.ts:519:21:519:21 | A | A |
| tst.ts:519:21:519:31 | A[typeof a] | () => number |
| tst.ts:519:23:519:30 | typeof a | symbol |
| tst.ts:519:30:519:30 | a | symbol |
| tstModuleCJS.cts:1:33:1:35 | 'a' | "a" |
| tstModuleCJS.cts:1:33:1:41 | 'a' \| 'b' | "a" \| "b" |
| tstModuleCJS.cts:1:39:1:41 | 'b' | "b" |
@@ -1290,6 +1303,7 @@ getTypeExprType
missingToString
referenceDefinition
| A | badTypes.ts:5:1:5:29 | interfa ... is.B {} |
| A | tst.ts:515:10:517:3 | class A ... };\\n } |
| Action | tst.ts:252:3:254:50 | type Ac ... ring }; |
| Alias<T> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
| Alias<number> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |

View File

@@ -508,4 +508,13 @@ module TS55 {
var str = obj[key].toUpperCase(); // Now okay, previously was error
}
}
}
}
namespace TS57{
declare const a: symbol;
export class A {
[a]() { return 1 };
}
declare const e1: A[typeof a]; // Now okay, previously was compilation error TS2538: Type 'symbol' cannot be used as an index type.
}

View File

@@ -1,3 +1,3 @@
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss
import semmle.javascript.security.dataflow.ServerSideUrlRedirectQuery as ServerSideUrlRedirect

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.(DataFlow::CallNode).getCalleeName() = "source" }

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.frameworks.data.internal.ApiGraphModels as ApiGraphModels
class TypeModelFromCodeQL extends ModelInput::TypeModel {

View File

@@ -1,5 +1,5 @@
import javascript
import testUtilities.InlineExpectationsTest
import utils.test.InlineExpectationsTest
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource }

View File

@@ -1,6 +1,6 @@
import javascript
import semmle.javascript.security.dataflow.TaintedPathQuery
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
deprecated class TaintedPathConsistency extends ConsistencyConfiguration {
TaintedPathConsistency() { this = "TaintedPathConsistency" }

View File

@@ -197,3 +197,25 @@ var server = http.createServer(function(req, res) {
cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK
cp.execFileSync("foobar", {cwd: path}); // NOT OK
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// Removal of forward-slash or dots.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to.
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute)
if (!pathModule.isAbsolute(path)) {
res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), ''))); // OK
}
});

View File

@@ -1,3 +1,3 @@
import javascript
import semmle.javascript.security.dataflow.TemplateObjectInjectionQuery
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.CommandInjectionQuery as CommandInjection
import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery as IndirectCommandInjection
import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironment

View File

@@ -628,3 +628,14 @@ module.exports.veryIndeirect = function (name) {
cp.exec("rm -rf " + name); // NOT OK
}
module.exports.sanitizer = function (name) {
var sanitized = "'" + name.replace(new RegExp("\'"), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // NOT OK
var sanitized = "'" + name.replace(new RegExp("\'", 'g'), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK
var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK -- Most likely should be okay and not flagged to reduce false positives.
}

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.DomBasedXssQuery
deprecated class ConsistencyConfig extends ConsistencyConfiguration {

View File

@@ -503,3 +503,10 @@ function Foo() {
};
Object.assign(this, obj);
}
function nonGlobalSanitizer() {
var target = document.location.search
$("#foo").html(target.replace(new RegExp("<|>"), '')); // NOT OK
$("#foo").html(target.replace(new RegExp("<|>", unknownFlags()), '')); // OK -- most likely good. We don't know what the flags are.
$("#foo").html(target.replace(new RegExp("<|>", "g"), '')); // OK
}

View File

@@ -1,3 +1,3 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss

View File

@@ -1,3 +1,3 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss

View File

@@ -1,3 +1,3 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.StoredXssQuery as StoredXss

View File

@@ -1,3 +1,3 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.UnsafeHtmlConstructionQuery as UnsafeHtmlConstruction

View File

@@ -1,3 +1,3 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.UnsafeJQueryPluginQuery as UnsafeJqueryPlugin

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.XssThroughDomQuery
deprecated class ConsistencyConfig extends ConsistencyConfiguration {

View File

@@ -1,4 +1,4 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection
import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection

View File

@@ -6,3 +6,4 @@
| tst.js:60:7:60:28 | s.repla ... '%25') | This replacement may double-escape '%' characters from $@. | tst.js:59:7:59:28 | s.repla ... '%26') | here |
| tst.js:68:10:70:38 | s.repla ... &amp;") | This replacement may double-escape '&' characters from $@. | tst.js:68:10:69:39 | s.repla ... apos;") | here |
| tst.js:79:10:79:66 | s.repla ... &amp;") | This replacement may double-escape '&' characters from $@. | tst.js:79:10:79:43 | s.repla ... epl[c]) | here |
| tst.js:99:10:101:49 | s.repla ... &amp;") | This replacement may double-escape '&' characters from $@. | tst.js:99:10:100:51 | s.repla ... apos;") | here |

View File

@@ -94,3 +94,21 @@ function testWithCapturedVar(x) {
function encodeDecodeEncode(s) {
return goodEncode(goodDecode(goodEncode(s)));
}
function badEncode(s) {
return s.replace(new RegExp("\"", "g"), "&quot;")
.replace(new RegExp("\'", "g"), "&apos;")
.replace(new RegExp("&", "g"), "&amp;"); // NOT OK
}
function goodEncode(s) {
return s.replace(new RegExp("\"", ""), "&quot;")
.replace(new RegExp("\'", ""), "&apos;")
.replace(new RegExp("&", ""), "&amp;"); // OK
}
function goodEncode(s) {
return s.replace(new RegExp("\"", unknownFlags()), "&quot;")
.replace(new RegExp("\'", unknownFlags()), "&apos;")
.replace(new RegExp("&", unknownFlags()), "&amp;"); // OK
}

View File

@@ -65,3 +65,9 @@
| tst.js:305:10:305:34 | s().rep ... ]/g,'') | This HTML sanitizer does not sanitize double quotes |
| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes |
| tst.js:320:9:329:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes |
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize ampersands |
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize double quotes |
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize single quotes |
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize ampersands |
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize double quotes |
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize single quotes |

View File

@@ -39,3 +39,4 @@
| tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < | <script |
| tst-multi-character-sanitization.js:148:3:148:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:148:41:148:41 | < | <script |
| tst-multi-character-sanitization.js:152:3:152:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:152:41:152:41 | < | <script |
| tst.js:341:9:341:44 | p.repla ... "), "") | This string may still contain $@, which may cause a path injection vulnerability. | tst.js:341:31:341:33 | \\. | ../ |

View File

@@ -29,3 +29,9 @@
| tst.js:149:2:149:24 | x.repla ... replace | This replaces only the first occurrence of "\\n". |
| tst.js:193:9:193:17 | s.replace | This replaces only the first occurrence of /'/. |
| tst.js:202:10:202:18 | p.replace | This replaces only the first occurrence of "/../". |
| tst.js:341:9:341:17 | p.replace | This replaces only the first occurrence of /\\.\\.//. |
| tst.js:345:9:345:17 | s.replace | This does not escape backslash characters in the input. |
| tst.js:349:9:349:17 | s.replace | This replaces only the first occurrence of /'/. |
| tst.js:353:9:353:17 | s.replace | This does not escape backslash characters in the input. |
| tst.js:362:2:362:10 | x.replace | This replaces only the first occurrence of /\n/. |
| tst.js:363:2:363:24 | x.repla ... replace | This replaces only the first occurrence of /\n/. |

View File

@@ -327,4 +327,41 @@ function incompleteComplexSanitizers() {
if (str === "\"")
return "&quot;";
}) + '"';
}
}
function typicalBadHtmlSanitizers(s) {
s().replace(new RegExp("[<>]", "g"),''); // NOT OK
}
function typicalBadHtmlSanitizers(s) {
s().replace(new RegExp("[<>]", unknown()),''); // NOT OK
}
function bad18NewRegExp(p) {
return p.replace(new RegExp("\\.\\./"), ""); // NOT OK
}
function bad4NewRegExpG(s) {
return s.replace(new RegExp("\'","g"), "\\$&"); // NOT OK
}
function bad4NewRegExp(s) {
return s.replace(new RegExp("\'"), "\\$&"); // NOT OK
}
function bad4NewRegExpUnknown(s) {
return s.replace(new RegExp("\'", unknownFlags()), "\\$&"); // NOT OK
}
function newlinesNewReGexp(s) {
require("child_process").execSync("which emacs").toString().replace(new RegExp("\n"), ""); // OK
x.replace(new RegExp("\n", "g"), "").replace(x, y); // OK
x.replace(x, y).replace(new RegExp("\n", "g"), ""); // OK
x.replace(new RegExp("\n"), "").replace(x, y); // NOT OK
x.replace(x, y).replace(new RegExp("\n"), ""); // NOT OK
x.replace(new RegExp("\n", unknownFlags()), "").replace(x, y); // OK
x.replace(x, y).replace(new RegExp("\n", unknownFlags()), ""); // OK
}

View File

@@ -2,6 +2,7 @@
| tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:73:1:74:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:107:1:108:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:76:9:76:20 | /\\/baz\\/bla/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ/BLA' will bypass the middleware. | tst.js:76:9:76:20 | /\\/baz\\/bla/ | pattern | tst.js:77:1:79:2 | app.get ... });\\n}) | case-insensitive path |
| tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ3/A' will bypass the middleware. | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | pattern | tst.js:87:1:89:2 | app.get ... });\\n}) | case-insensitive path |
| tst.js:91:9:91:40 | /\\/summ ... ntGame/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/CURRENTGAME' will bypass the middleware. | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | pattern | tst.js:93:1:95:2 | app.get ... O");\\n}) | case-insensitive path |

View File

@@ -93,3 +93,16 @@ app.use(/\/summonerByName|\/currentGame/,apiLimit1, apiLimit2);
app.get('/currentGame', function (req, res) {
res.send("FOO");
});
app.get(
new RegExp('^/bar(.*)?', unknownFlag()), // OK - Might be OK if the unknown flag evaluates to case insensitive one
unknown(),
function(req, res, next) {
if (req.params.blah) {
next();
}
}
);
app.get('/bar/*', (req, res) => { // OK - not a middleware
});

View File

@@ -175,3 +175,11 @@ const debug = require('debug')('test');
const myPasscode = foo();
console.log(myPasscode); // NOT OK
});
(function () {
console.log(password.replace(/./g, "*")); // OK
console.log(password.replace(new RegExp(".", "g"), "*")); // OK
console.log(password.replace(new RegExp("."), "*")); // NOT OK
console.log(password.replace(new RegExp(".", unknownFlags()), "*")); // OK -- Most likely not a problem.
console.log(password.replace(new RegExp("pre_._suf", "g"), "*")); // OK
})();

View File

@@ -130,6 +130,9 @@
| polynomial-redos.js:133:22:133:23 | f+ | Strings starting with 'f' and with many repetitions of 'f' can start matching anywhere after the start of the preceeding ff+G |
| polynomial-redos.js:136:25:136:26 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X |
| polynomial-redos.js:140:33:140:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| polynomial-redos.js:141:33:141:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| polynomial-redos.js:142:33:142:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| regexplib/address.js:27:3:27:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) |
| regexplib/address.js:27:48:27:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) |
| regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) |

View File

@@ -136,4 +136,8 @@ app.use(function(req, res) {
modified3.replace(/hh+I/g, "b"); // NOT OK
tainted.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*X/); // NOT OK
modified3.replace(new RegExp("hh+I", "g"), "b"); // NOT OK
modified3.replace(new RegExp("hh+I", unknownFlags()), "b"); // NOT OK
modified3.replace(new RegExp("hh+I", ""), "b"); // NOT OK
});

View File

@@ -1,3 +1,3 @@
import javascript
import semmle.javascript.security.dataflow.UnsafeDeserializationQuery
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking

View File

@@ -1,2 +1,2 @@
query: Security/CWE-611/Xxe.ql
postprocess: testUtilities/InlineExpectationsTestQuery.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -92,3 +92,16 @@ app.get("argv", function(req, res) {
new RegExp(`^${process.argv[1]}/Foo/bar.app$`); // NOT OK
});
app.get("argv", function(req, res) {
var input = req.param("input");
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]"), "\\$&");
new RegExp(sanitized); // NOT OK
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]", "g"), "\\$&");
new RegExp(sanitized); // OK
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]", unknownFlags()), "\\$&");
new RegExp(sanitized); // OK -- Most likely not a problem.
});

View File

@@ -1,3 +1,3 @@
import javascript
import semmle.javascript.security.dataflow.ResourceExhaustionQuery
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking

View File

@@ -1,5 +1,5 @@
import javascript
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery
deprecated class Config extends ConsistencyConfiguration {

View File

@@ -123,3 +123,10 @@ app.get('/assign', (req, res) => {
Object.assign(dest, plainObj[taint]);
dest[taint] = taint; // OK - 'dest' is not Object.prototype itself (but possibly a copy)
});
app.get('/foo', (req, res) => {
let obj = {};
obj[req.query.x.replace(new RegExp('_', 'g'), '')].x = 'foo'; // OK
obj[req.query.x.replace(new RegExp('_', ''), '')].x = 'foo'; // NOT OK
obj[req.query.x.replace(new RegExp('_', unknownFlags()), '')].x = 'foo'; // OK
});

View File

@@ -1,7 +1,7 @@
import javascript
import semmle.javascript.security.dataflow.RequestForgeryQuery as RequestForgery
import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery as ClientSideRequestForgery
deprecated import testUtilities.ConsistencyChecking
deprecated import utils.test.ConsistencyChecking
query predicate resultInWrongFile(DataFlow::Node node) {
exists(string filePattern |

View File

@@ -7,3 +7,5 @@
| tst.js:53:10:53:34 | bothOnl ... fects() | the $@ does not return anything, yet the return value is used. | tst.js:48:2:50:5 | functio ... )\\n } | function onlySideEffects2 |
| tst.js:76:12:76:46 | [1,2,3] ... n, 3)}) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:76:27:76:45 | n => {equals(n, 3)} | callback function |
| tst.js:80:12:80:50 | filter( ... 3) } ) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:80:28:80:48 | x => { ... x, 3) } | callback function |
| tst.js:114:12:114:56 | [1,2,3] ... 3); }) | the $@ does not return anything, yet the return value from the call to findLastIndex is used. | tst.js:114:34:114:55 | n => { ... , 3); } | callback function |
| tst.js:117:12:117:51 | [1,2,3] ... 3); }) | the $@ does not return anything, yet the return value from the call to findLast is used. | tst.js:117:29:117:50 | n => { ... , 3); } | callback function |

View File

@@ -107,3 +107,13 @@ class Bar extends Foo {
console.log(super()); // OK.
}
}
() => {
let equals = (x, y) => { return x === y; };
var foo = [1,2,3].findLastIndex(n => { equals(n, 3); }) // NOT OK
console.log(foo);
var foo = [1,2,3].findLast(n => { equals(n, 3); }) // NOT OK
console.log(foo);
}

View File

@@ -1,187 +0,0 @@
/**
* DEPRECATED, but can be imported with a `deprecated import`.
*
* Will be replaced with standardized inline test expectations in the future.
*/
import javascript
/**
* A configuration for consistency checking.
* Used to specify where the alerts are (the positives)
* And which files should be included in the consistency-check.
*
* If no configuration is specified, then the default is that the all sinks from a `DataFlow::Configuration` are alerts, and all files are consistency-checked.
*/
abstract deprecated class ConsistencyConfiguration extends string {
bindingset[this]
ConsistencyConfiguration() { any() }
/**
* Gets an alert that should be checked for consistency.
* The alert must match with a `NOT OK` comment.
*
* And likewise a `OK` comment must not have a corresponding alert on the same line.
*/
DataFlow::Node getAnAlert() { result = getASink() }
/**
* Gets a file to include in the consistency checking.
*/
File getAFile() { none() }
}
/**
* A string that either equals a `ConsistencyConfiguration`, or the empty string if no such configuration exists.
*
* Is used internally to match a configuration or lack thereof.
*/
deprecated final private class Conf extends string {
Conf() {
this instanceof ConsistencyConfiguration
or
not exists(ConsistencyConfiguration c) and
this = ""
}
}
/**
* A comment that asserts whether a result exists at that line or not.
* Can optionally include `[INCONSISTENCY]` to indicate that a consistency issue is expected at the location
*/
private class AssertionComment extends Comment {
boolean shouldHaveAlert;
AssertionComment() {
if this.getText().regexpMatch("\\s*(NOT OK|BAD).*")
then shouldHaveAlert = true
else (
this.getText().regexpMatch("\\s*(OK|GOOD).*") and shouldHaveAlert = false
)
}
/**
* Holds if there should be an alert at this location
*/
predicate shouldHaveAlert() { shouldHaveAlert = true }
/**
* Holds if a consistency issue is expected at this location.
*/
predicate expectConsistencyError() { this.getText().matches("%[INCONSISTENCY]%") }
}
deprecated private DataFlow::Node getASink() {
exists(DataFlow::Configuration cfg | cfg.hasFlow(_, result))
}
/**
* Gets all the alerts for consistency consistency checking from a configuration `conf`.
*/
deprecated private DataFlow::Node alerts(Conf conf) {
result = conf.(ConsistencyConfiguration).getAnAlert()
or
not exists(ConsistencyConfiguration r) and
result = getASink() and
conf = ""
}
/**
* Gets an alert in `file` at `line` for configuration `conf`.
* The `line` can be either the first or the last line of the alert.
* And if no expression exists at `line`, then an alert on the next line is used.
*/
deprecated private DataFlow::Node getAlert(File file, int line, Conf conf) {
result = alerts(conf) and
result.getFile() = file and
(result.hasLocationInfo(_, _, _, line, _) or result.hasLocationInfo(_, line, _, _, _))
or
// The comment can be right above the result, so an alert also counts for the line above.
not exists(Expr e |
e.getFile() = file and [e.getLocation().getStartLine(), e.getLocation().getEndLine()] = line
) and
result = alerts(conf) and
result.getFile() = file and
result.hasLocationInfo(_, line + 1, _, _, _)
}
/**
* Gets a comment that asserts either the existence or the absence of an alert in `file` at `line`.
*/
private AssertionComment getComment(File file, int line) {
result.getLocation().getEndLine() = line and
result.getFile() = file
}
/**
* Holds if there is a false positive in `file` at `line` for configuration `conf`.
*/
deprecated private predicate falsePositive(File file, int line, AssertionComment comment, Conf conf) {
exists(getAlert(file, line, conf)) and
comment = getComment(file, line) and
not comment.shouldHaveAlert()
}
/**
* Holds if there is a false negative in `file` at `line` for configuration `conf`.
*/
deprecated private predicate falseNegative(File file, int line, AssertionComment comment, Conf conf) {
not exists(getAlert(file, line, conf)) and
comment = getComment(file, line) and
comment.shouldHaveAlert()
}
/**
* Gets a file that should be included for consistency checking for configuration `conf`.
*/
deprecated private File getATestFile(string conf) {
not exists(any(ConsistencyConfiguration res).getAFile()) and
result = any(LineComment comment).getFile() and
(conf = "" or conf instanceof ConsistencyConfiguration)
or
result = conf.(ConsistencyConfiguration).getAFile()
}
/**
* Gets a description of the configuration that has a sink in `file` at `line` for configuration `conf`.
* Or the empty string
*/
bindingset[file, line]
deprecated private string getSinkDescription(File file, int line, Conf conf) {
not exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf))) and
result = ""
or
exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf)) |
result = " for " + c
)
}
/**
* Holds if there is a consistency-issue at `location` with description `msg` for configuration `conf`.
* The consistency issue an unexpected false positive/negative.
* Or that false positive/negative was expected, and none were found.
*/
deprecated query predicate consistencyIssue(
string location, string msg, string commentText, Conf conf
) {
exists(File file, int line |
file = getATestFile(conf) and location = file.getRelativePath() + ":" + line
|
exists(AssertionComment comment |
comment.getText().trim() = commentText and comment = getComment(file, line)
|
falsePositive(file, line, comment, conf) and
not comment.expectConsistencyError() and
msg = "did not expect an alert, but found an alert" + getSinkDescription(file, line, conf)
or
falseNegative(file, line, comment, conf) and
not comment.expectConsistencyError() and
msg = "expected an alert, but found none"
or
not falsePositive(file, line, comment, conf) and
not falseNegative(file, line, comment, conf) and
comment.expectConsistencyError() and
msg = "expected consistency issue, but found no such issue (" + comment.getText().trim() + ")"
)
)
}

View File

@@ -1,8 +0,0 @@
/**
* Inline expectation tests for JS.
* See `shared/util/codeql/util/test/InlineExpectationsTest.qll`
*/
private import codeql.util.test.InlineExpectationsTest
private import internal.InlineExpectationsTestImpl
import Make<Impl>

View File

@@ -1,21 +0,0 @@
/**
* @kind test-postprocess
*/
private import javascript
private import codeql.util.test.InlineExpectationsTest as T
private import internal.InlineExpectationsTestImpl
import T::TestPostProcessing
import T::TestPostProcessing::Make<Impl, Input>
private module Input implements T::TestPostProcessing::InputSig<Impl> {
string getRelativeUrl(Location location) {
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
f = location.getFile()
|
result =
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
)
}
}

View File

@@ -1,25 +0,0 @@
/**
* Inline flow tests for JavaScript.
* See `shared/util/codeql/dataflow/test/InlineFlowTest.qll`
*/
private import javascript
private import semmle.javascript.Locations
private import codeql.dataflow.test.InlineFlowTest
private import semmle.javascript.dataflow.internal.sharedlib.DataFlowArg
private import semmle.javascript.frameworks.data.internal.ApiGraphModelsExtensions as ApiGraphModelsExtensions
private import internal.InlineExpectationsTestImpl
private module FlowTestImpl implements InputSig<Location, JSDataFlow> {
import testUtilities.InlineFlowTestUtil
bindingset[src, sink]
string getArgString(DataFlow::Node src, DataFlow::Node sink) {
(if exists(getSourceArgString(src)) then result = getSourceArgString(src) else result = "") and
exists(sink)
}
predicate interpretModelForTest = ApiGraphModelsExtensions::interpretModelForTest/2;
}
import InlineFlowTestMake<Location, JSDataFlow, JSTaintFlow, Impl, FlowTestImpl>

View File

@@ -1,21 +0,0 @@
/**
* Defines the default source and sink recognition for `InlineFlowTest.qll`.
*
* We reuse these predicates in some type-tracking tests that don't wish to bring in the
* test configuration from `InlineFlowTest`.
*/
private import javascript
predicate defaultSource(DataFlow::Node src) { src.(DataFlow::CallNode).getCalleeName() = "source" }
predicate defaultSink(DataFlow::Node sink) {
exists(DataFlow::CallNode call | call.getCalleeName() = "sink" | sink = call.getAnArgument())
}
bindingset[src]
string getSourceArgString(DataFlow::Node src) {
src.(DataFlow::CallNode).getAnArgument().getStringValue() = result
or
src.(DataFlow::ParameterNode).getName() = result
}

View File

@@ -1,37 +0,0 @@
import javascript
import semmle.javascript.dataflow.FlowSummary
class MkSummary extends SummarizedCallable {
private CallExpr mkSummary;
MkSummary() {
mkSummary.getCalleeName() = "mkSummary" and
this =
"mkSummary at " + mkSummary.getFile().getRelativePath() + ":" +
mkSummary.getLocation().getStartLine()
}
override DataFlow::InvokeNode getACallSimple() {
result = mkSummary.flow().(DataFlow::CallNode).getAnInvocation()
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
preservesValue = true and
(
// mkSummary(input, output)
input = mkSummary.getArgument(0).getStringValue() and
output = mkSummary.getArgument(1).getStringValue()
or
// mkSummary([
// [input1, output1],
// [input2, output2],
// ...
// ])
exists(ArrayExpr pair |
pair = mkSummary.getArgument(0).(ArrayExpr).getAnElement() and
input = pair.getElement(0).getStringValue() and
output = pair.getElement(1).getStringValue()
)
)
}
}

View File

@@ -1,19 +0,0 @@
private import javascript
private signature class LegacyConfigSig {
predicate hasFlow(DataFlow::Node source, DataFlow::Node sink);
}
module DataFlowDiff<DataFlow::GlobalFlowSig NewFlow, LegacyConfigSig LegacyConfig> {
query predicate legacyDataFlowDifference(
DataFlow::Node source, DataFlow::Node sink, string message
) {
NewFlow::flow(source, sink) and
not any(LegacyConfig cfg).hasFlow(source, sink) and
message = "only flow with NEW data flow library"
or
not NewFlow::flow(source, sink) and
any(LegacyConfig cfg).hasFlow(source, sink) and
message = "only flow with OLD data flow library"
}
}

View File

@@ -1,17 +0,0 @@
private import javascript as JS
private import codeql.util.test.InlineExpectationsTest
module Impl implements InlineExpectationsTestSig {
private import javascript
final private class LineCommentFinal = LineComment;
class ExpectationComment extends LineCommentFinal {
string getContents() { result = this.getText() }
/** Gets this element's location. */
Location getLocation() { result = super.getLocation() }
}
class Location = JS::Location;
}